├── README.md └── springmvc ├── pom.xml ├── springmvc.iml ├── src └── main │ ├── java │ └── com │ │ └── hyy │ │ ├── controller │ │ └── GreetingController.java │ │ ├── model │ │ ├── Greeting.java │ │ └── HelloMessage.java │ │ └── websocket │ │ └── WebSocketConfig.java │ ├── resources │ └── config │ │ └── spring │ │ └── dispatcher.xml │ └── webapp │ ├── WEB-INF │ └── web.xml │ ├── js │ └── stomp.js │ ├── websocket.html │ └── websocket.jsp └── target ├── classes ├── com │ └── hyy │ │ ├── controller │ │ └── GreetingController.class │ │ ├── model │ │ ├── Greeting.class │ │ └── HelloMessage.class │ │ └── websocket │ │ └── WebSocketConfig.class └── config │ └── spring │ └── dispatcher.xml ├── springmvc-1.1.0.war └── springmvc-1.1.0 ├── META-INF └── MANIFEST.MF ├── WEB-INF ├── classes │ ├── com │ │ └── hyy │ │ │ ├── controller │ │ │ ├── GoController.class │ │ │ └── GreetingController.class │ │ │ ├── model │ │ │ ├── Greeting.class │ │ │ └── HelloMessage.class │ │ │ └── websocket │ │ │ └── WebSocketConfig.class │ └── config │ │ └── spring │ │ └── dispatcher.xml ├── lib │ ├── aopalliance-1.0.jar │ ├── commons-logging-1.2.jar │ ├── jackson-annotations-2.5.0.jar │ ├── jackson-core-2.5.3.jar │ ├── jackson-databind-2.5.3.jar │ ├── javax.servlet-api-3.1.0.jar │ ├── spring-aop-4.2.8.RELEASE.jar │ ├── spring-beans-4.2.8.RELEASE.jar │ ├── spring-context-4.2.8.RELEASE.jar │ ├── spring-context-support-4.2.8.RELEASE.jar │ ├── spring-core-4.2.8.RELEASE.jar │ ├── spring-expression-4.2.8.RELEASE.jar │ ├── spring-messaging-4.2.8.RELEASE.jar │ ├── spring-web-4.2.8.RELEASE.jar │ ├── spring-webmvc-4.2.8.RELEASE.jar │ └── spring-websocket-4.2.8.RELEASE.jar └── web.xml ├── index.jsp ├── websocket.html └── websocket.jsp /README.md: -------------------------------------------------------------------------------- 1 | # SpringWebSocket-SockJS-STOMP 2 | SpringWebSocket+SockJS+STOMP实现广播、点对点通信 3 | -------------------------------------------------------------------------------- /springmvc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.hyy 8 | springmvc 9 | war 10 | 1.1.0 11 | springmvc 12 | 13 | 14 | 4.2.8.RELEASE 15 | 16 | 17 | 18 | 19 | nexus 20 | nexus 21 | http://192.168.2.65:81/nexus/content/repositories/public 22 | 23 | 24 | 25 | 26 | 27 | nexus 28 | nexus 29 | http://192.168.2.65:81/nexus/content/repositories/public 30 | 31 | 32 | 33 | 34 | 35 | org.springframework 36 | spring-core 37 | ${spring.version} 38 | 39 | 40 | org.springframework 41 | spring-context 42 | ${spring.version} 43 | 44 | 45 | org.springframework 46 | spring-messaging 47 | ${spring.version} 48 | 49 | 50 | org.springframework 51 | spring-websocket 52 | ${spring.version} 53 | 54 | 55 | org.springframework 56 | spring-webmvc 57 | ${spring.version} 58 | 59 | 60 | org.springframework 61 | spring-web 62 | ${spring.version} 63 | 64 | 65 | javax.servlet 66 | javax.servlet-api 67 | 3.1.0 68 | provided 69 | 70 | 71 | org.springframework 72 | spring-beans 73 | ${spring.version} 74 | 75 | 76 | org.springframework 77 | spring-aop 78 | ${spring.version} 79 | 80 | 81 | org.springframework 82 | spring-context-support 83 | ${spring.version} 84 | 85 | 86 | com.fasterxml.jackson.core 87 | jackson-databind 88 | 2.5.3 89 | runtime 90 | 91 | 92 | -------------------------------------------------------------------------------- /springmvc/springmvc.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | file://$MODULE_DIR$/src/main/resources/config/spring/dispatcher.xml 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /springmvc/src/main/java/com/hyy/controller/GreetingController.java: -------------------------------------------------------------------------------- 1 | package com.hyy.controller; 2 | 3 | import com.hyy.model.Greeting; 4 | import com.hyy.model.HelloMessage; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.messaging.handler.annotation.Header; 7 | import org.springframework.messaging.handler.annotation.Headers; 8 | import org.springframework.messaging.handler.annotation.MessageMapping; 9 | import org.springframework.messaging.handler.annotation.SendTo; 10 | import org.springframework.messaging.simp.SimpMessageSendingOperations; 11 | import org.springframework.messaging.simp.annotation.SendToUser; 12 | import org.springframework.messaging.simp.annotation.SubscribeMapping; 13 | import org.springframework.stereotype.Controller; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestMethod; 16 | import org.springframework.web.bind.annotation.RequestParam; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | import java.util.Map; 20 | 21 | /** 22 | * Created by haoyuyang on 2016/11/25. 23 | */ 24 | @RestController 25 | public class GreetingController { 26 | 27 | @Autowired 28 | private SimpMessageSendingOperations simpMessageSendingOperations; 29 | 30 | /** 31 | * 表示服务端可以接收客户端通过主题“/app/hello”发送过来的消息,客户端需要在主题"/topic/hello"上监听并接收服务端发回的消息 32 | * @param topic 33 | * @param headers 34 | */ 35 | @MessageMapping("/hello") //"/hello"为WebSocketConfig类中registerStompEndpoints()方法配置的 36 | @SendTo("/topic/greetings") 37 | public void greeting(@Header("atytopic") String topic, @Headers Map headers) { 38 | System.out.println("connected successfully...."); 39 | System.out.println(topic); 40 | System.out.println(headers); 41 | } 42 | 43 | /** 44 | * 这里用的是@SendToUser,这就是发送给单一客户端的标志。本例中, 45 | * 客户端接收一对一消息的主题应该是“/user/” + 用户Id + “/message” ,这里的用户id可以是一个普通的字符串,只要每个用户端都使用自己的id并且服务端知道每个用户的id就行。 46 | * @return 47 | */ 48 | @MessageMapping("/message") 49 | @SendToUser("/message") 50 | public Greeting handleSubscribe() { 51 | System.out.println("this is the @SubscribeMapping('/marco')"); 52 | return new Greeting("I am a msg from SubscribeMapping('/macro')."); 53 | } 54 | 55 | /** 56 | * 测试对指定用户发送消息方法 57 | * @return 58 | */ 59 | @RequestMapping(path = "/send", method = RequestMethod.GET) 60 | public Greeting send() { 61 | simpMessageSendingOperations.convertAndSendToUser("1", "/message", new Greeting("I am a msg from SubscribeMapping('/macro').")); 62 | return new Greeting("I am a msg from SubscribeMapping('/macro')."); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /springmvc/src/main/java/com/hyy/model/Greeting.java: -------------------------------------------------------------------------------- 1 | package com.hyy.model; 2 | 3 | public class Greeting { 4 | private String content; 5 | 6 | public Greeting(String content) { 7 | this.content = content; 8 | } 9 | 10 | public String getContent() { 11 | return content; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /springmvc/src/main/java/com/hyy/model/HelloMessage.java: -------------------------------------------------------------------------------- 1 | package com.hyy.model; 2 | 3 | public class HelloMessage { 4 | private String name; 5 | 6 | public String getName() { 7 | return name; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /springmvc/src/main/java/com/hyy/websocket/WebSocketConfig.java: -------------------------------------------------------------------------------- 1 | package com.hyy.websocket; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.messaging.simp.config.MessageBrokerRegistry; 5 | import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; 6 | import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; 7 | import org.springframework.web.socket.config.annotation.StompEndpointRegistry; 8 | 9 | /** 10 | * Created by haoyuyang on 2016/11/25. 11 | */ 12 | @Configuration 13 | @EnableWebSocketMessageBroker 14 | public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { 15 | 16 | /** 17 | * 将"/hello"路径注册为STOMP端点,这个路径与发送和接收消息的目的路径有所不同,这是一个端点,客户端在订阅或发布消息到目的地址前,要连接该端点, 18 | * 即用户发送请求url="/applicationName/hello"与STOMP server进行连接。之后再转发到订阅url; 19 | * PS:端点的作用——客户端在订阅或发布消息到目的地址前,要连接该端点。 20 | * @param stompEndpointRegistry 21 | */ 22 | public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { 23 | //在网页上可以通过"/applicationName/hello"来和服务器的WebSocket连接 24 | stompEndpointRegistry.addEndpoint("/hello").setAllowedOrigins("*").withSockJS(); 25 | } 26 | 27 | /** 28 | * 配置了一个简单的消息代理,如果不重载,默认情况下回自动配置一个简单的内存消息代理,用来处理以"/topic"为前缀的消息。这里重载configureMessageBroker()方法, 29 | * 消息代理将会处理前缀为"/topic"和"/queue"的消息。 30 | * @param registry 31 | */ 32 | @Override 33 | public void configureMessageBroker(MessageBrokerRegistry registry) { 34 | //应用程序以/app为前缀,代理目的地以/topic、/queue为前缀 35 | registry.enableSimpleBroker("/topic", "/user"); 36 | registry.setApplicationDestinationPrefixes("/app"); 37 | registry.setUserDestinationPrefix("/user"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /springmvc/src/main/resources/config/spring/dispatcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /springmvc/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | index.jsp 8 | 9 | 10 | 11 | contextConfigLocation 12 | classpath:config/spring/*.xml 13 | 14 | 15 | 16 | org.springframework.web.context.ContextLoaderListener 17 | 18 | 19 | 20 | dispatcherServlet 21 | org.springframework.web.servlet.DispatcherServlet 22 | 23 | contextConfigLocation 24 | classpath:config/spring/*.xml 25 | 26 | 1 27 | true 28 | 29 | 30 | dispatcherServlet 31 | / 32 | 33 | 34 | 35 | encodingFilter 36 | org.springframework.web.filter.CharacterEncodingFilter 37 | 38 | encoding 39 | UTF-8 40 | 41 | 42 | forceEncoding 43 | true 44 | 45 | true 46 | 47 | 48 | 49 | encodingFilter 50 | /* 51 | 52 | -------------------------------------------------------------------------------- /springmvc/src/main/webapp/js/stomp.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.7.1 2 | 3 | /* 4 | Stomp Over WebSocket http://www.jmesnil.net/stomp-websocket/doc/ | Apache License V2.0 5 | 6 | Copyright (C) 2010-2013 [Jeff Mesnil](http://jmesnil.net/) 7 | Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com) 8 | */ 9 | 10 | (function() { 11 | var Byte, Client, Frame, Stomp, 12 | __hasProp = {}.hasOwnProperty, 13 | __slice = [].slice; 14 | 15 | Byte = { 16 | LF: '\x0A', 17 | NULL: '\x00' 18 | }; 19 | 20 | Frame = (function() { 21 | var unmarshallSingle; 22 | 23 | function Frame(command, headers, body) { 24 | this.command = command; 25 | this.headers = headers != null ? headers : {}; 26 | this.body = body != null ? body : ''; 27 | } 28 | 29 | Frame.prototype.toString = function() { 30 | var lines, name, skipContentLength, value, _ref; 31 | lines = [this.command]; 32 | skipContentLength = this.headers['content-length'] === false ? true : false; 33 | if (skipContentLength) { 34 | delete this.headers['content-length']; 35 | } 36 | _ref = this.headers; 37 | for (name in _ref) { 38 | if (!__hasProp.call(_ref, name)) continue; 39 | value = _ref[name]; 40 | lines.push("" + name + ":" + value); 41 | } 42 | if (this.body && !skipContentLength) { 43 | lines.push("content-length:" + (Frame.sizeOfUTF8(this.body))); 44 | } 45 | lines.push(Byte.LF + this.body); 46 | return lines.join(Byte.LF); 47 | }; 48 | 49 | Frame.sizeOfUTF8 = function(s) { 50 | if (s) { 51 | return encodeURI(s).match(/%..|./g).length; 52 | } else { 53 | return 0; 54 | } 55 | }; 56 | 57 | unmarshallSingle = function(data) { 58 | var body, chr, command, divider, headerLines, headers, i, idx, len, line, start, trim, _i, _j, _len, _ref, _ref1; 59 | divider = data.search(RegExp("" + Byte.LF + Byte.LF)); 60 | headerLines = data.substring(0, divider).split(Byte.LF); 61 | command = headerLines.shift(); 62 | headers = {}; 63 | trim = function(str) { 64 | return str.replace(/^\s+|\s+$/g, ''); 65 | }; 66 | _ref = headerLines.reverse(); 67 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 68 | line = _ref[_i]; 69 | idx = line.indexOf(':'); 70 | headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1)); 71 | } 72 | body = ''; 73 | start = divider + 2; 74 | if (headers['content-length']) { 75 | len = parseInt(headers['content-length']); 76 | body = ('' + data).substring(start, start + len); 77 | } else { 78 | chr = null; 79 | for (i = _j = start, _ref1 = data.length; start <= _ref1 ? _j < _ref1 : _j > _ref1; i = start <= _ref1 ? ++_j : --_j) { 80 | chr = data.charAt(i); 81 | if (chr === Byte.NULL) { 82 | break; 83 | } 84 | body += chr; 85 | } 86 | } 87 | return new Frame(command, headers, body); 88 | }; 89 | 90 | Frame.unmarshall = function(datas) { 91 | var frame, frames, last_frame, r; 92 | frames = datas.split(RegExp("" + Byte.NULL + Byte.LF + "*")); 93 | r = { 94 | frames: [], 95 | partial: '' 96 | }; 97 | r.frames = (function() { 98 | var _i, _len, _ref, _results; 99 | _ref = frames.slice(0, -1); 100 | _results = []; 101 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 102 | frame = _ref[_i]; 103 | _results.push(unmarshallSingle(frame)); 104 | } 105 | return _results; 106 | })(); 107 | last_frame = frames.slice(-1)[0]; 108 | if (last_frame === Byte.LF || (last_frame.search(RegExp("" + Byte.NULL + Byte.LF + "*$"))) !== -1) { 109 | r.frames.push(unmarshallSingle(last_frame)); 110 | } else { 111 | r.partial = last_frame; 112 | } 113 | return r; 114 | }; 115 | 116 | Frame.marshall = function(command, headers, body) { 117 | var frame; 118 | frame = new Frame(command, headers, body); 119 | return frame.toString() + Byte.NULL; 120 | }; 121 | 122 | return Frame; 123 | 124 | })(); 125 | 126 | Client = (function() { 127 | var now; 128 | 129 | function Client(ws) { 130 | this.ws = ws; 131 | this.ws.binaryType = "arraybuffer"; 132 | this.counter = 0; 133 | this.connected = false; 134 | this.heartbeat = { 135 | outgoing: 10000, 136 | incoming: 10000 137 | }; 138 | this.maxWebSocketFrameSize = 16 * 1024; 139 | this.subscriptions = {}; 140 | this.partialData = ''; 141 | } 142 | 143 | Client.prototype.debug = function(message) { 144 | var _ref; 145 | return typeof window !== "undefined" && window !== null ? (_ref = window.console) != null ? _ref.log(message) : void 0 : void 0; 146 | }; 147 | 148 | now = function() { 149 | if (Date.now) { 150 | return Date.now(); 151 | } else { 152 | return new Date().valueOf; 153 | } 154 | }; 155 | 156 | Client.prototype._transmit = function(command, headers, body) { 157 | var out; 158 | out = Frame.marshall(command, headers, body); 159 | if (typeof this.debug === "function") { 160 | this.debug(">>> " + out); 161 | } 162 | while (true) { 163 | if (out.length > this.maxWebSocketFrameSize) { 164 | this.ws.send(out.substring(0, this.maxWebSocketFrameSize)); 165 | out = out.substring(this.maxWebSocketFrameSize); 166 | if (typeof this.debug === "function") { 167 | this.debug("remaining = " + out.length); 168 | } 169 | } else { 170 | return this.ws.send(out); 171 | } 172 | } 173 | }; 174 | 175 | Client.prototype._setupHeartbeat = function(headers) { 176 | var serverIncoming, serverOutgoing, ttl, v, _ref, _ref1; 177 | if ((_ref = headers.version) !== Stomp.VERSIONS.V1_1 && _ref !== Stomp.VERSIONS.V1_2) { 178 | return; 179 | } 180 | _ref1 = (function() { 181 | var _i, _len, _ref1, _results; 182 | _ref1 = headers['heart-beat'].split(","); 183 | _results = []; 184 | for (_i = 0, _len = _ref1.length; _i < _len; _i++) { 185 | v = _ref1[_i]; 186 | _results.push(parseInt(v)); 187 | } 188 | return _results; 189 | })(), serverOutgoing = _ref1[0], serverIncoming = _ref1[1]; 190 | if (!(this.heartbeat.outgoing === 0 || serverIncoming === 0)) { 191 | ttl = Math.max(this.heartbeat.outgoing, serverIncoming); 192 | if (typeof this.debug === "function") { 193 | this.debug("send PING every " + ttl + "ms"); 194 | } 195 | this.pinger = Stomp.setInterval(ttl, (function(_this) { 196 | return function() { 197 | _this.ws.send(Byte.LF); 198 | return typeof _this.debug === "function" ? _this.debug(">>> PING") : void 0; 199 | }; 200 | })(this)); 201 | } 202 | if (!(this.heartbeat.incoming === 0 || serverOutgoing === 0)) { 203 | ttl = Math.max(this.heartbeat.incoming, serverOutgoing); 204 | if (typeof this.debug === "function") { 205 | this.debug("check PONG every " + ttl + "ms"); 206 | } 207 | return this.ponger = Stomp.setInterval(ttl, (function(_this) { 208 | return function() { 209 | var delta; 210 | delta = now() - _this.serverActivity; 211 | if (delta > ttl * 2) { 212 | if (typeof _this.debug === "function") { 213 | _this.debug("did not receive server activity for the last " + delta + "ms"); 214 | } 215 | return _this.ws.close(); 216 | } 217 | }; 218 | })(this)); 219 | } 220 | }; 221 | 222 | Client.prototype._parseConnect = function() { 223 | var args, connectCallback, errorCallback, headers; 224 | args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 225 | headers = {}; 226 | switch (args.length) { 227 | case 2: 228 | headers = args[0], connectCallback = args[1]; 229 | break; 230 | case 3: 231 | if (args[1] instanceof Function) { 232 | headers = args[0], connectCallback = args[1], errorCallback = args[2]; 233 | } else { 234 | headers.login = args[0], headers.passcode = args[1], connectCallback = args[2]; 235 | } 236 | break; 237 | case 4: 238 | headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3]; 239 | break; 240 | default: 241 | headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3], headers.host = args[4]; 242 | } 243 | return [headers, connectCallback, errorCallback]; 244 | }; 245 | 246 | Client.prototype.connect = function() { 247 | var args, errorCallback, headers, out; 248 | args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 249 | out = this._parseConnect.apply(this, args); 250 | headers = out[0], this.connectCallback = out[1], errorCallback = out[2]; 251 | if (typeof this.debug === "function") { 252 | this.debug("Opening Web Socket..."); 253 | } 254 | this.ws.onmessage = (function(_this) { 255 | return function(evt) { 256 | var arr, c, client, data, frame, messageID, onreceive, subscription, unmarshalledData, _i, _len, _ref, _results; 257 | data = typeof ArrayBuffer !== 'undefined' && evt.data instanceof ArrayBuffer ? (arr = new Uint8Array(evt.data), typeof _this.debug === "function" ? _this.debug("--- got data length: " + arr.length) : void 0, ((function() { 258 | var _i, _len, _results; 259 | _results = []; 260 | for (_i = 0, _len = arr.length; _i < _len; _i++) { 261 | c = arr[_i]; 262 | _results.push(String.fromCharCode(c)); 263 | } 264 | return _results; 265 | })()).join('')) : evt.data; 266 | _this.serverActivity = now(); 267 | if (data === Byte.LF) { 268 | if (typeof _this.debug === "function") { 269 | _this.debug("<<< PONG"); 270 | } 271 | return; 272 | } 273 | if (typeof _this.debug === "function") { 274 | _this.debug("<<< " + data); 275 | } 276 | unmarshalledData = Frame.unmarshall(_this.partialData + data); 277 | _this.partialData = unmarshalledData.partial; 278 | _ref = unmarshalledData.frames; 279 | _results = []; 280 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 281 | frame = _ref[_i]; 282 | switch (frame.command) { 283 | case "CONNECTED": 284 | if (typeof _this.debug === "function") { 285 | _this.debug("connected to server " + frame.headers.server); 286 | } 287 | _this.connected = true; 288 | _this._setupHeartbeat(frame.headers); 289 | _results.push(typeof _this.connectCallback === "function" ? _this.connectCallback(frame) : void 0); 290 | break; 291 | case "MESSAGE": 292 | subscription = frame.headers.subscription; 293 | onreceive = _this.subscriptions[subscription] || _this.onreceive; 294 | if (onreceive) { 295 | client = _this; 296 | messageID = frame.headers["message-id"]; 297 | frame.ack = function(headers) { 298 | if (headers == null) { 299 | headers = {}; 300 | } 301 | return client.ack(messageID, subscription, headers); 302 | }; 303 | frame.nack = function(headers) { 304 | if (headers == null) { 305 | headers = {}; 306 | } 307 | return client.nack(messageID, subscription, headers); 308 | }; 309 | _results.push(onreceive(frame)); 310 | } else { 311 | _results.push(typeof _this.debug === "function" ? _this.debug("Unhandled received MESSAGE: " + frame) : void 0); 312 | } 313 | break; 314 | case "RECEIPT": 315 | _results.push(typeof _this.onreceipt === "function" ? _this.onreceipt(frame) : void 0); 316 | break; 317 | case "ERROR": 318 | _results.push(typeof errorCallback === "function" ? errorCallback(frame) : void 0); 319 | break; 320 | default: 321 | _results.push(typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0); 322 | } 323 | } 324 | return _results; 325 | }; 326 | })(this); 327 | this.ws.onclose = (function(_this) { 328 | return function() { 329 | var msg; 330 | msg = "Whoops! Lost connection to " + _this.ws.url; 331 | if (typeof _this.debug === "function") { 332 | _this.debug(msg); 333 | } 334 | _this._cleanUp(); 335 | return typeof errorCallback === "function" ? errorCallback(msg) : void 0; 336 | }; 337 | })(this); 338 | return this.ws.onopen = (function(_this) { 339 | return function() { 340 | if (typeof _this.debug === "function") { 341 | _this.debug('Web Socket Opened...'); 342 | } 343 | headers["accept-version"] = Stomp.VERSIONS.supportedVersions(); 344 | headers["heart-beat"] = [_this.heartbeat.outgoing, _this.heartbeat.incoming].join(','); 345 | return _this._transmit("CONNECT", headers); 346 | }; 347 | })(this); 348 | }; 349 | 350 | Client.prototype.disconnect = function(disconnectCallback, headers) { 351 | if (headers == null) { 352 | headers = {}; 353 | } 354 | this._transmit("DISCONNECT", headers); 355 | this.ws.onclose = null; 356 | this.ws.close(); 357 | this._cleanUp(); 358 | return typeof disconnectCallback === "function" ? disconnectCallback() : void 0; 359 | }; 360 | 361 | Client.prototype._cleanUp = function() { 362 | this.connected = false; 363 | if (this.pinger) { 364 | Stomp.clearInterval(this.pinger); 365 | } 366 | if (this.ponger) { 367 | return Stomp.clearInterval(this.ponger); 368 | } 369 | }; 370 | 371 | Client.prototype.send = function(destination, headers, body) { 372 | if (headers == null) { 373 | headers = {}; 374 | } 375 | if (body == null) { 376 | body = ''; 377 | } 378 | headers.destination = destination; 379 | return this._transmit("SEND", headers, body); 380 | }; 381 | 382 | Client.prototype.subscribe = function(destination, callback, headers) { 383 | var client; 384 | if (headers == null) { 385 | headers = {}; 386 | } 387 | if (!headers.id) { 388 | headers.id = "sub-" + this.counter++; 389 | } 390 | headers.destination = destination; 391 | this.subscriptions[headers.id] = callback; 392 | this._transmit("SUBSCRIBE", headers); 393 | client = this; 394 | return { 395 | id: headers.id, 396 | unsubscribe: function() { 397 | return client.unsubscribe(headers.id); 398 | } 399 | }; 400 | }; 401 | 402 | Client.prototype.unsubscribe = function(id) { 403 | delete this.subscriptions[id]; 404 | return this._transmit("UNSUBSCRIBE", { 405 | id: id 406 | }); 407 | }; 408 | 409 | Client.prototype.begin = function(transaction) { 410 | var client, txid; 411 | txid = transaction || "tx-" + this.counter++; 412 | this._transmit("BEGIN", { 413 | transaction: txid 414 | }); 415 | client = this; 416 | return { 417 | id: txid, 418 | commit: function() { 419 | return client.commit(txid); 420 | }, 421 | abort: function() { 422 | return client.abort(txid); 423 | } 424 | }; 425 | }; 426 | 427 | Client.prototype.commit = function(transaction) { 428 | return this._transmit("COMMIT", { 429 | transaction: transaction 430 | }); 431 | }; 432 | 433 | Client.prototype.abort = function(transaction) { 434 | return this._transmit("ABORT", { 435 | transaction: transaction 436 | }); 437 | }; 438 | 439 | Client.prototype.ack = function(messageID, subscription, headers) { 440 | if (headers == null) { 441 | headers = {}; 442 | } 443 | headers["message-id"] = messageID; 444 | headers.subscription = subscription; 445 | return this._transmit("ACK", headers); 446 | }; 447 | 448 | Client.prototype.nack = function(messageID, subscription, headers) { 449 | if (headers == null) { 450 | headers = {}; 451 | } 452 | headers["message-id"] = messageID; 453 | headers.subscription = subscription; 454 | return this._transmit("NACK", headers); 455 | }; 456 | 457 | return Client; 458 | 459 | })(); 460 | 461 | Stomp = { 462 | VERSIONS: { 463 | V1_0: '1.0', 464 | V1_1: '1.1', 465 | V1_2: '1.2', 466 | supportedVersions: function() { 467 | return '1.1,1.0'; 468 | } 469 | }, 470 | client: function(url, protocols) { 471 | var klass, ws; 472 | if (protocols == null) { 473 | protocols = ['v10.stomp', 'v11.stomp']; 474 | } 475 | klass = Stomp.WebSocketClass || WebSocket; 476 | ws = new klass(url, protocols); 477 | return new Client(ws); 478 | }, 479 | over: function(ws) { 480 | return new Client(ws); 481 | }, 482 | Frame: Frame 483 | }; 484 | 485 | if (typeof exports !== "undefined" && exports !== null) { 486 | exports.Stomp = Stomp; 487 | } 488 | 489 | if (typeof window !== "undefined" && window !== null) { 490 | Stomp.setInterval = function(interval, f) { 491 | return window.setInterval(f, interval); 492 | }; 493 | Stomp.clearInterval = function(id) { 494 | return window.clearInterval(id); 495 | }; 496 | window.Stomp = Stomp; 497 | } else if (!exports) { 498 | self.Stomp = Stomp; 499 | } 500 | 501 | }).call(this); 502 | -------------------------------------------------------------------------------- /springmvc/src/main/webapp/websocket.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello WebSocket 5 | 6 | 7 | 8 | 89 | 90 | 91 | 93 |
94 |
95 | 96 | 97 | 98 |
99 |
100 | 101 | 102 |

103 |
104 |
105 | 106 | -------------------------------------------------------------------------------- /springmvc/src/main/webapp/websocket.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: haoyuyang 4 | Date: 2016/11/25 5 | Time: 上午11:41 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | Hello WebSocket 12 | 13 | 14 | 15 | 97 | 98 | 99 | 101 |
102 |
103 | 104 | 105 | 106 |
107 |
108 | 109 | 110 |

111 |
112 |
113 | 114 | 115 | -------------------------------------------------------------------------------- /springmvc/target/classes/com/hyy/controller/GreetingController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/classes/com/hyy/controller/GreetingController.class -------------------------------------------------------------------------------- /springmvc/target/classes/com/hyy/model/Greeting.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/classes/com/hyy/model/Greeting.class -------------------------------------------------------------------------------- /springmvc/target/classes/com/hyy/model/HelloMessage.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/classes/com/hyy/model/HelloMessage.class -------------------------------------------------------------------------------- /springmvc/target/classes/com/hyy/websocket/WebSocketConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/classes/com/hyy/websocket/WebSocketConfig.class -------------------------------------------------------------------------------- /springmvc/target/classes/config/spring/dispatcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0.war -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Built-By: haoyuyang 3 | Created-By: IntelliJ IDEA 4 | Build-Jdk: 1.8.0_112 5 | 6 | -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/controller/GoController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/controller/GoController.class -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/controller/GreetingController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/controller/GreetingController.class -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/model/Greeting.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/model/Greeting.class -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/model/HelloMessage.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/model/HelloMessage.class -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/websocket/WebSocketConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/classes/com/hyy/websocket/WebSocketConfig.class -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/classes/config/spring/dispatcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/aopalliance-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/aopalliance-1.0.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/commons-logging-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/commons-logging-1.2.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/jackson-annotations-2.5.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/jackson-annotations-2.5.0.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/jackson-core-2.5.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/jackson-core-2.5.3.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/jackson-databind-2.5.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/jackson-databind-2.5.3.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/javax.servlet-api-3.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/javax.servlet-api-3.1.0.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-aop-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-aop-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-beans-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-beans-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-context-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-context-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-context-support-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-context-support-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-core-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-core-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-expression-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-expression-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-messaging-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-messaging-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-web-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-web-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-webmvc-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-webmvc-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-websocket-4.2.8.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haoyuyang/SpringWebSocket-SockJS-STOMP/8697bc49b19f41387c4490390e1fe33bff1c7f06/springmvc/target/springmvc-1.1.0/WEB-INF/lib/spring-websocket-4.2.8.RELEASE.jar -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | index.jsp 8 | 9 | 10 | 11 | contextConfigLocation 12 | classpath:config/spring/*.xml 13 | 14 | 15 | 16 | org.springframework.web.context.ContextLoaderListener 17 | 18 | 19 | 20 | dispatcherServlet 21 | org.springframework.web.servlet.DispatcherServlet 22 | 23 | contextConfigLocation 24 | classpath:config/spring/*.xml 25 | 26 | 1 27 | true 28 | 29 | 30 | dispatcherServlet 31 | / 32 | 33 | 34 | 35 | encodingFilter 36 | org.springframework.web.filter.CharacterEncodingFilter 37 | 38 | encoding 39 | UTF-8 40 | 41 | 42 | forceEncoding 43 | true 44 | 45 | true 46 | 47 | 48 | 49 | encodingFilter 50 | /* 51 | 52 | -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/index.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: haoyuyang 4 | Date: 2016/11/8 5 | Time: 下午1:27 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | Title 12 | 13 | 14 | Hello World 15 | 16 | 17 | -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/websocket.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello WebSocket 5 | 6 | 7 | 8 | 89 | 90 | 91 | 93 |
94 |
95 | 96 | 97 | 98 |
99 |
100 | 101 | 102 |

103 |
104 |
105 | 106 | -------------------------------------------------------------------------------- /springmvc/target/springmvc-1.1.0/websocket.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: haoyuyang 4 | Date: 2016/11/25 5 | Time: 上午11:41 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | Hello WebSocket 12 | 13 | 14 | 15 | 97 | 98 | 99 | 101 |
102 |
103 | 104 | 105 | 106 |
107 |
108 | 109 | 110 |

111 |
112 |
113 | 114 | 115 | --------------------------------------------------------------------------------