{"id":1128,"date":"2016-08-09T21:51:43","date_gmt":"2016-08-09T12:51:43","guid":{"rendered":"http:\/\/blog.moramcnt.com\/?p=1128"},"modified":"2016-08-11T18:08:56","modified_gmt":"2016-08-11T09:08:56","slug":"%ec%a0%84%ec%9e%90%ec%a0%95%eb%b6%80%ed%94%84%eb%a0%88%ec%9e%84%ec%9b%8c%ed%81%ac3-5%ec%97%90%ec%84%9c-websocket-%ec%82%ac%ec%9a%a9%ed%95%98%ea%b8%b0","status":"publish","type":"post","link":"http:\/\/blog.moramcnt.com\/?p=1128","title":{"rendered":"\uc804\uc790\uc815\ubd80\ud504\ub808\uc784\uc6cc\ud06c(3.5)\uc5d0\uc11c websocket \uc0ac\uc6a9\ud558\uae30"},"content":{"rendered":"<p>\ub2e4\uc74c\uc740 \uc804\uc790\uc815\ubd80\ud504\ub808\uc784\uc6cc\ud06c 3.5\uc5d0\uc11c \uc6f9\uc18c\ucf13\uc744 \uc0ac\uc6a9\ud558\uae30 \uc704\ud55c \uc808\ucc28\uc784<\/p>\n<p>1. \uc694\uad6c\uc0ac\ud56d<br \/>\n1) \uc804\uc790\uc815\ubd80\ud504\ub808\uc784\uc6cc\ud06c : 3.5<br \/>\n2) \uc544\ud30c\uce58 \ud1b0\ucea3 : 7.0.70 \uc774\uc0c1(\ub108\ubb34 \ubc84\uc804\uc774 \ub0ae\uc544\ub3c4 \uc6f9\uc18c\ucf13\uc744 \uc9c0\uc6d0\uc548\ud558\ubbc0\ub85c \uc720\uc758\ud574\uc57c \ud568)<br \/>\n3) spring framework : 4.0.9.RELEASE<br \/>\n  &#8211; \uc804\uc790\uc815\ubd80 \ud504\ub808\uc784 3.5 \ubc84\uc804\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uc2a4\ud504\ub9c1 \ubc84\uc804, \ub354 \ub192\uc77c\uc218 \uc788\uc9c0\ub9cc \ub2e4\ub978 \ubb38\uc81c \ubc1c\uc0dd\ud560\uc218 \uc788\uc74c. \uc2e4\uc81c\ub85c \uc2a4\ud504\ub9c1 4.1\uc5d0\uc11c\ub294<br \/>\n    \uadf8\uac04 \uc798 \uc368\uc654\ub358 jackson\uc758 \uc9c0\uc6d0\uc774 \uc911\ub2e8\ub418\uc5b4 \ub2e4\ub978\uac83\uc73c\ub85c \ub300\uccb4\ud574\uc57c \ud558\ub294\ub4f1 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4.<br \/>\n4) JDK : 1.7 \uc774\uc0c1<br \/>\n5) SockJs : \uc775\uc2a4\ud50c\ub85c\ub7ec \ub0ae\uc740\ubc84\uc804\ub3c4 \uc9c0\uc6d0\ud558\uae30 \uc704\ud558\uc5ec \uc0ac\uc6a9<\/p>\n<p>2. \uba54\uc774\ube10 POM\uc5d0 \ucd94\uac00<\/p>\n<pre>\r\n<!-- \uc804\uc790\uc815\ubd80\ud504\ub808\uc784\uc6cc\ud06c 3.5 \ubc84\uc804\uc758 \uc2a4\ud504\ub9c1\ubc84\uc804 : 4.0.9 -->\r\n<springframework.version>4.0.9.RELEASE<\/springframework.version>\t\t\t\t\r\n<\/pre>\n<pre>\r\n<dependency> \r\n\t<groupId>org.springframework<\/groupId> \r\n\t<artifactId>spring-context<\/artifactId> \r\n\t<version>${springframework.version}<\/version> \r\n<\/dependency> \t\t\r\n<dependency>\r\n\t<groupId>org.springframework<\/groupId>\r\n\t<artifactId>spring-core<\/artifactId>\r\n\t<version>${springframework.version}<\/version>\r\n<\/dependency>\t\t\r\n<dependency>\r\n\t<groupId>org.springframework<\/groupId>\r\n\t<artifactId>spring-beans<\/artifactId>\r\n\t<version>${springframework.version}<\/version>\r\n<\/dependency>\t\t\r\n<dependency>\r\n\t<groupId>org.springframework<\/groupId>\r\n\t<artifactId>spring-web<\/artifactId>\r\n\t<version>${springframework.version}<\/version>\r\n<\/dependency>\r\n<dependency>\r\n\t<groupId>org.springframework<\/groupId>\r\n\t<artifactId>spring-webmvc<\/artifactId>\r\n\t<version>${springframework.version}<\/version>\r\n<\/dependency>\r\n<!-- Spring WebSocket  -->\r\n<dependency>\r\n\t<groupId>org.springframework<\/groupId>\r\n\t<artifactId>spring-websocket<\/artifactId>\r\n\t<version>${springframework.version}<\/version>\r\n<\/dependency>\r\n<dependency> \r\n\t<groupId>javax.servlet<\/groupId> \r\n\t<artifactId>javax.servlet-api<\/artifactId> \r\n\t<version>3.1.0<\/version> \r\n\t<scope>provided<\/scope> \r\n<\/dependency>\r\n<dependency>\r\n\t<groupId>javax.websocket<\/groupId>\r\n\t<artifactId>javax.websocket-api<\/artifactId>\r\n\t<version>1.0<\/version>\r\n\t<!-- scope\uc774 \uc5c6\uc73c\uba74 \uc2e4\ud589\uc2dc classcastexception \ubc1c\uc0dd -->\r\n\t<scope>provided<\/scope>            \r\n<\/dependency>\r\n<\/pre>\n<p>3. \uc6f9\uc18c\ucf13 \uc124\uc815<\/p>\n<pre>\r\n@Configuration\r\n@EnableWebMvc\r\n@EnableWebSocket\r\npublic class WebSockConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer\r\n{\r\n\t@Override\r\n\tpublic void registerWebSocketHandlers(WebSocketHandlerRegistry wshrRegistry)\r\n\t{\r\n\t\t\/\/ \uc6f9\uc18c\ucf13\r\n\t\twshrRegistry.addHandler(monHandler(), \"\/websocket\/monHandler.ws\")\r\n\t\t\t.addInterceptors(new MonHandshakeInterceptor());\r\n\t\t\r\n\t\t\/\/ SockJs\t\r\n\t\twshrRegistry.addHandler(monHandler(), \"\/websocket\/monHandler.sockjs\")\r\n\t\t\t.addInterceptors(new MonHandshakeInterceptor())\r\n\t\t\t.withSockJS();\r\n\t}\r\n\r\n\t@Bean\r\n\tpublic MonHandler monHandler()\r\n\t{\r\n\t\treturn new MonHandler();\r\n\t}\r\n\r\n    @Override\r\n    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)\r\n    {\r\n        configurer.enable();\r\n    }\r\n}\r\n<\/pre>\n<p>4. DispatcherServletInitializer<\/p>\n<pre>\r\npublic class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {\r\n\r\n\t@Override\r\n\tprotected Class<?>[] getRootConfigClasses()\r\n\t{\r\n\t\treturn null;\r\n\t}\r\n\r\n\t@Override\r\n\tprotected Class<?>[] getServletConfigClasses()\r\n\t{\r\n\t\treturn new Class<?>[] { WebSockConfig.class };\r\n\t}\r\n\r\n\t@Override\r\n\tprotected String[] getServletMappings()\r\n\t{\r\n\t\treturn new String[] { \"\/\" };\r\n\t\t\/\/return new String[] {\"*.do\", \"*.json\"};\r\n\t}\r\n\r\n\t@Override\r\n\tprotected void customizeRegistration(Dynamic registration)\r\n\t{\r\n\t\tregistration.setInitParameter(\"dispatchOptionsRequest\", \"true\");\r\n\t}\r\n}\r\n\r\n<\/pre>\n<p>5. \uc778\ud130\uc149\ud130<br \/>\n &#8211; \uc778\ud130\uc149\ud130\ub97c \uc4f4 \uc774\uc720\ub294 \uc0ac\uc2e4 SockJs\uc5d0\uc11c \ub118\uae34 \ud30c\ub77c\ubbf8\ud130\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud574\uc11c\uc774\ub2e4. \uc989 \uc544\ub798\uc640 \uac19\uc774 userId\ub97c \ub118\uacbc\uc744\ub54c<br \/>\n   \ubc1b\uc744\uc218 \uc788\ub294\uacf3\uc740 \uc778\ud130\uc149\ud130\uc774\uae30 \ub54c\ubb38\uc774\ub2e4.<\/p>\n<pre>\r\nwsSockJs = new SockJS(\"http:\/\/localhost:8080\/websocket\/monHandler.sockjs?userId=yomile\");\r\n<\/pre>\n<pre>\r\n \r\n\r\npublic class MonHandshakeInterceptor extends HttpSessionHandshakeInterceptor \r\n{\r\n\t@Override\r\n\tpublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> mpAttributes) throws Exception\r\n\t{\r\n\t\tServletServerHttpRequest sshRequest = (ServletServerHttpRequest)request;\r\n        HttpServletRequest hsrRequest =  sshRequest.getServletRequest();\r\n\r\n        String strUserId = hsrRequest.getParameter(\"userId\");\r\n        mpAttributes.put(\"userId\", strUserId);\r\n        return super.beforeHandshake(request, response, wsHandler, mpAttributes);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex)\r\n\t{\r\n\t\tsuper.afterHandshake(request, response, wsHandler, ex);\r\n\t}\r\n}\r\n\r\n<\/pre>\n<p>6. \uc6f9\uc18c\ucf13 \ud578\ub4e4\ub7ec<br \/>\n &#8211; \uc704\uc758 \uc778\ud14c\uc149\ud130\uc5d0\uc11c mpAttributes\uc5d0 \ud30c\ub77c\ubbf8\ud130\uac12\uc744 \ub2e4\uc2dc \ub123\uc5b4\uc8fc\uac8c \ub418\uba74 \uc544\ub798 \uc6f9\uc18c\ucf13 \ud578\ub4e4\ub7ec\uc5d0\uc11c\ub294 WebSocketSession\uc758 getAttributes\ub97c<br \/>\n   \uc774\uc6a9\ud558\uc5ec \uac12\uc744 \ube7c\uc5b4 \ub0bc\uc218 \uc788\uac8c \ub41c\ub2e4. \uacb0\uad6d JavaScript\uc758 Sockjs\uc5d0\uc11c \ub123\uc740 \ud30c\ub77c\ubbf8\ud130 \uac12\uc774 \ucd5c\uc885\uc801\uc73c\ub85c \uc5ec\uae30\uae4c\uc9c0 \uc62c\uc218 \uc788\uac8c \ub41c\ub2e4.<\/p>\n<pre>\r\n\r\n\/\/@Component\r\npublic class MonHandler extends TextWebSocketHandler \r\n{\r\n    private static Logger mStatLogger = LoggerFactory.getLogger(MonHandler.class);\r\n\r\n\tprivate List<WebSocketSession> mLstSession = null;\r\n\r\n\tpublic MonHandler()\r\n\t{\r\n\t\tmLstSession = new ArrayList<WebSocketSession>();\r\n\t}\r\n \r\n\t@Override\r\n\tpublic void afterConnectionEstablished(WebSocketSession wssSession) throws Exception\r\n\t{\r\n\t\tMap<String, Object> mpParam = wssSession.getAttributes();\r\n    \tString strUserId = (String)mpParam.get(\"userId\");\r\n\t\tmStatLogger.debug(\" \uc811\uc18d, UserId:\"+ strUserId +\",SessionId:\"+ wssSession.getId() +\", \uc5f0\uacb0 IP:\" + wssSession.getRemoteAddress().getHostName() );\r\n\t\tmLstSession.add(wssSession);\r\n\t}\r\n\r\n\t@Override\r\n\tprotected void handleTextMessage(WebSocketSession wssCurSession, TextMessage tmMsg) throws Exception\r\n\t{\r\n\t\tmStatLogger.debug(\"*MonHandler.handleTextMessage\");\r\n\t\tmStatLogger.info(\"{}\ub85c \ubd80\ud130 {} \ubc1b\uc74c\", wssCurSession.getId(), tmMsg.getPayload());\r\n\t\tMonVO clsMonVO = MonVO.convert(tmMsg.getPayload());\r\n\t\t\r\n\t\tmStatLogger.debug(\" -clsMonVO.getTarget():\"+ clsMonVO.getTarget());\r\n\t\tmStatLogger.debug(\" -clsMonVO.getMessage():\"+ clsMonVO.getMessage());\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tMap<String, Object> mpCurParam = wssCurSession.getAttributes();\r\n\t\tString strCurUserId = (String)mpCurParam.get(\"userId\");\r\n\t\tmStatLogger.debug(\" - CurUserId:\"+ strCurUserId);\r\n\t\t\r\n\t\t\r\n\t\t\/\/\uc5f0\uacb0\ub41c \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \uba54\uc2dc\uc9c0 \uc804\uc1a1\r\n\t\tfor(WebSocketSession wssSession : mLstSession)\r\n\t\t{\r\n\t\t\tMap<String, Object> mpParam = wssSession.getAttributes();\r\n\t\t\tString strUserId = (String)mpParam.get(\"userId\");\r\n\t\t\tif(clsMonVO.getTarget().equals(strUserId) == true)\r\n\t\t\t{\r\n\t\t\t\t\/\/ \uc804\uc1a1\ub300\uc0c1\ud55c\ud14c\ub9cc \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b8\ub2e4.\t    \t\r\n\t\t\t\twssSession.sendMessage(new TextMessage(clsMonVO.getMessage()));\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n    \r\n\t@Override  \r\n\tpublic void handleTransportError(WebSocketSession wssSession, Throwable exception) throws Exception\r\n\t{  \r\n\t\tmStatLogger.debug(\"*MonHandler.handleTransportError\");\r\n\t\tif(wssSession.isOpen() == true) wssSession.close();  \r\n\t\tmLstSession.remove(wssSession);  \r\n\t}  \r\n    \r\n\r\n\t@Override\r\n\tpublic void afterConnectionClosed(WebSocketSession wssSession, CloseStatus status) throws Exception\r\n\t{\r\n\t\tmStatLogger.debug(\"*MonHandler.afterConnectionClosed\");\r\n\t\tmStatLogger.info(\"{} \uc5f0\uacb0 \ub04a\uae40.\", wssSession.getId());\r\n\t\tmLstSession.remove(wssSession);\r\n\t}\t\r\n}\r\n\r\n<\/pre>\n<p>7. JSP \uc124\uc815<\/p>\n<pre>\r\n<%@ page language=\"java\" contentType=\"text\/html; charset=EUC-KR\" pageEncoding=\"EUC-KR\"%>\r\n<!DOCTYPE html>\r\n<html>\r\n\t<head>\r\n\t\t<meta charset=\"utf-8\">\r\n\t\t<title>test<\/title>\r\n\t\t<script type=\"text\/javascript\" src=\"\/common\/lib\/jquery\/js\/jquery-1.11.1.min.js\"><\/script>\r\n\t\t<script type=\"text\/javascript\" src=\"\/common\/lib\/json\/js\/json2.js\"><\/script>\r\n\t\t<script type=\"text\/javascript\" src=\"\/common\/lib\/sockjs-client\/v1.1.1\/sockjs-1.1.1.min.js\"><\/script>\r\n\t\t<script type=\"text\/javascript\">\r\n\t\t\tvar mWsSocket;\r\n\t\t\t\r\n\t\t\t$(document).ready(function() {\r\n\t\t\t\t\r\n\t\t\t\tvar strUrl = \"http:\/\/localhost:8080\/websocket\/monHandler.sockjs?userId=yomile\";\r\n\t\t\t\tmWsSocket = new SockJS(strUrl);\r\n\t\t\t\tmWsSocket.onmessage = onMessage;\r\n\t\t\t\tmWsSocket.onclose = onClose;\r\n\t\t\t\tmWsSocket.onopen = function() {\r\n\t\t\t\t\t\/*\r\n\t\t\t\t\tvar arrData = {};\r\n\t\t\t\t\tarrData.target = \"yomile\";\r\n\t\t\t\t\tarrData.message = \"\uc628\ub3c4:100\";\r\n\t\t \t\t\tmWsSocket.send(JSON.stringify(arrData));\r\n\t\t\t\t\t*\/\r\n\t\t\t\t};\t\t\r\n\t\t\t});\r\n\t\t\r\n\t\t\tfunction onMessage(event)\r\n\t\t\t{\r\n\t\t\t\talert(\"\uc218\uc2e0\ub370\uc774\ud130: \" + event.data);\r\n\t\t\t\t\/\/mWsSocket.close();\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tfunction onClose(event)\r\n\t\t\t{\r\n\t\t\t\talert(\"Close\");\r\n\t\t\t}\r\n\t\t<\/script>\r\n\t<\/head>\r\n<body>\r\n \r\n<\/body>\r\n<\/html>\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\ub2e4\uc74c\uc740 \uc804\uc790\uc815\ubd80\ud504\ub808\uc784\uc6cc\ud06c 3.5\uc5d0\uc11c \uc6f9\uc18c\ucf13\uc744 \uc0ac\uc6a9\ud558\uae30 \uc704\ud55c \uc808\ucc28\uc784 1. \uc694\uad6c\uc0ac\ud56d 1) \uc804\uc790\uc815\ubd80\ud504\ub808\uc784\uc6cc\ud06c : 3.5 2) \uc544\ud30c\uce58 \ud1b0\ucea3 : 7.0.70 \uc774\uc0c1(\ub108\ubb34 \ubc84\uc804\uc774 \ub0ae\uc544\ub3c4 \uc6f9\uc18c\ucf13\uc744 \uc9c0\uc6d0\uc548\ud558\ubbc0\ub85c \uc720\uc758\ud574\uc57c \ud568) 3) spring framework : 4.0.9.RELEASE &#8211; \uc804\uc790\uc815\ubd80 \ud504\ub808\uc784 3.5 \ubc84\uc804\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uc2a4\ud504\ub9c1 \ubc84\uc804, \ub354 \ub192\uc77c\uc218 \uc788\uc9c0\ub9cc \ub2e4\ub978 \ubb38\uc81c \ubc1c\uc0dd\ud560\uc218 \uc788\uc74c. \uc2e4\uc81c\ub85c \uc2a4\ud504\ub9c1 4.1\uc5d0\uc11c\ub294 \uadf8\uac04 \uc798 \uc368\uc654\ub358 jackson\uc758 \uc9c0\uc6d0\uc774 \uc911\ub2e8\ub418\uc5b4 \ub2e4\ub978\uac83\uc73c\ub85c [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[6,203,7],"tags":[200,199,202,201],"class_list":["post-1128","post","type-post","status-publish","format-standard","hentry","category-java","category-javascript","category-7","tag-sockjs","tag-websocket","tag-202","tag--3-5"],"_links":{"self":[{"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=\/wp\/v2\/posts\/1128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1128"}],"version-history":[{"count":8,"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=\/wp\/v2\/posts\/1128\/revisions"}],"predecessor-version":[{"id":1237,"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=\/wp\/v2\/posts\/1128\/revisions\/1237"}],"wp:attachment":[{"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1128"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.moramcnt.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}