Hí mn,
Hôm nay mình sẽ hướng dẫn mn setup 1 project Java Spring boot + Socket.io Client đơn giản nhất.
MÌnh đã research trên internet các tutorial về đề tài này, hầu hết chúng đều hướng dẫn sử dụng lib này https://github.com/mrniko/netty-socketio.
Có một nhược điểm của nó là nó được implement trên một server Netty có sẵn, thế nên nếu sử dụng Spring boot để tích hợp thì chúng ta sẽ phải sử dụng 2 port.
- Khiến cho proj setup bị phức tạp khi ta phải config 2 domain trong quá trình dev và prod.
- Khó khăn trong việc tích hợp security giữa Socket.io server và Spring security.
Không dài dòng nữa, chúng ta bắt tay vào làm thôi.
Website quen thuộc của Springer dev.
https://start.spring.io/
Dependencies:
- JDK 17
- Spring boot 2.x
- Spring web
- Websocket
Đây là github của Socket.io java server
- https://github.com/trinopoty/socket.io-server-java
- https://trinopoty.github.io/socket.io-server-java/
Mn thêm dependency này vào nha.
1 2 3 4 5 6 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>io.socket<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>socket.io-server<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>4.0.1<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> |
Tạo proj dir theo cấu trúc ntn.
Classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 | <span class="token comment">/** * @Author HuyVu * @CreatedDate 2/24/2023 1:41 PM */</span> <span class="token keyword">package</span> <span class="token namespace">io<span class="token punctuation">.</span>huyvu<span class="token punctuation">.</span>springbootsocketio<span class="token punctuation">.</span>config<span class="token punctuation">.</span>socketio</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">io<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>engineio<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">EngineIoServer</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">io<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>engineio<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">EngineIoServerOptions</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">io<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>socketio<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">SocketIoNamespace</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">io<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>socketio<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">SocketIoServer</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">io<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>socketio<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">SocketIoSocket</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Bean</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Configuration</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">List</span><span class="token punctuation">;</span> <span class="token annotation punctuation">@Configuration</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">BeanConfig</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@Bean</span> <span class="token class-name">EngineIoServer</span> <span class="token function">engineIoServer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">EngineIoServerOptions</span> opt <span class="token operator">=</span> <span class="token class-name">EngineIoServerOptions</span><span class="token punctuation">.</span><span class="token function">newFromDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> opt<span class="token punctuation">.</span><span class="token function">setCorsHandlingDisabled</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">EngineIoServer</span> eioServer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EngineIoServer</span><span class="token punctuation">(</span>opt<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> eioServer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Bean</span> <span class="token class-name">SocketIoServer</span> <span class="token function">socketIoServer</span><span class="token punctuation">(</span><span class="token class-name">EngineIoServer</span> eioServer<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">SocketIoServer</span> sioServer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SocketIoServer</span><span class="token punctuation">(</span>eioServer<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">SocketIoNamespace</span> namespace <span class="token operator">=</span> sioServer<span class="token punctuation">.</span><span class="token function">namespace</span><span class="token punctuation">(</span><span class="token string">"/mynamespace"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> namespace<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"connection"</span><span class="token punctuation">,</span> args <span class="token operator">-></span> <span class="token punctuation">{</span> <span class="token class-name">SocketIoSocket</span> socket <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">SocketIoSocket</span><span class="token punctuation">)</span> args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"Client "</span> <span class="token operator">+</span> socket<span class="token punctuation">.</span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">" ("</span> <span class="token operator">+</span> socket<span class="token punctuation">.</span><span class="token function">getInitialHeaders</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"remote_addr"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">") has connected."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> socket<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"message"</span><span class="token punctuation">,</span> args1 <span class="token operator">-></span> <span class="token punctuation">{</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"[Client "</span> <span class="token operator">+</span> socket<span class="token punctuation">.</span><span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"] "</span> <span class="token operator">+</span> <span class="token class-name">List</span><span class="token punctuation">.</span><span class="token function">of</span><span class="token punctuation">(</span>args1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token string">"Heo khô đi những kỉ niệm xưa kia"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> sioServer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <span class="token keyword">package</span> <span class="token namespace">io<span class="token punctuation">.</span>huyvu<span class="token punctuation">.</span>springbootsocketio<span class="token punctuation">.</span>config<span class="token punctuation">.</span>socketio</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">Configuration</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>config<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">EnableWebSocket</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>config<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">WebSocketConfigurer</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>config<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">WebSocketHandlerRegistry</span><span class="token punctuation">;</span> <span class="token annotation punctuation">@Configuration</span> <span class="token annotation punctuation">@EnableWebSocket</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">EngineIoConfigurator</span> <span class="token keyword">implements</span> <span class="token class-name">WebSocketConfigurer</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">EngineIoHandler</span> mEngineIoHandler<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token class-name">EngineIoConfigurator</span><span class="token punctuation">(</span><span class="token class-name">EngineIoHandler</span> engineIoHandler<span class="token punctuation">)</span> <span class="token punctuation">{</span> mEngineIoHandler <span class="token operator">=</span> engineIoHandler<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">registerWebSocketHandlers</span><span class="token punctuation">(</span><span class="token class-name">WebSocketHandlerRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span> registry<span class="token punctuation">.</span><span class="token function">addHandler</span><span class="token punctuation">(</span>mEngineIoHandler<span class="token punctuation">,</span> <span class="token string">"/socket.io/"</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">addInterceptors</span><span class="token punctuation">(</span>mEngineIoHandler<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">setAllowedOrigins</span><span class="token punctuation">(</span><span class="token string">"*"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | <span class="token keyword">package</span> <span class="token namespace">io<span class="token punctuation">.</span>huyvu<span class="token punctuation">.</span>springbootsocketio<span class="token punctuation">.</span>config<span class="token punctuation">.</span>socketio</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">io<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>engineio<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">EngineIoServer</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">io<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>engineio<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">EngineIoWebSocket</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">io<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>engineio<span class="token punctuation">.</span>server<span class="token punctuation">.</span>utils<span class="token punctuation">.</span></span><span class="token class-name">ParseQS</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>http<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">ServerHttpRequest</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>http<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">ServerHttpResponse</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype<span class="token punctuation">.</span></span><span class="token class-name">Controller</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RequestMapping</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>bind<span class="token punctuation">.</span>annotation<span class="token punctuation">.</span></span><span class="token class-name">RequestMethod</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>socket<span class="token punctuation">.</span></span><span class="token operator">*</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>web<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>server<span class="token punctuation">.</span></span><span class="token class-name">HandshakeInterceptor</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span></span><span class="token class-name">HttpServletRequest</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">javax<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>http<span class="token punctuation">.</span></span><span class="token class-name">HttpServletResponse</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io<span class="token punctuation">.</span></span><span class="token class-name">IOException</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">HashMap</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">List</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span></span><span class="token class-name">Map</span><span class="token punctuation">;</span> <span class="token annotation punctuation">@Controller</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">EngineIoHandler</span> <span class="token keyword">implements</span> <span class="token class-name">HandshakeInterceptor</span><span class="token punctuation">,</span> <span class="token class-name">WebSocketHandler</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> ATTRIBUTE_ENGINE_IO_BRIDGE <span class="token operator">=</span> <span class="token string">"engine.io.bridge"</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> ATTRIBUTE_ENGINE_IO_QUERY <span class="token operator">=</span> <span class="token string">"engine.io.query"</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token class-name">String</span> ATTRIBUTE_ENGINE_IO_HEADERS <span class="token operator">=</span> <span class="token string">"engine.io.headers"</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">EngineIoServer</span> mEngineIoServer<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token class-name">EngineIoHandler</span><span class="token punctuation">(</span><span class="token class-name">EngineIoServer</span> engineIoServer<span class="token punctuation">)</span> <span class="token punctuation">{</span> mEngineIoServer <span class="token operator">=</span> engineIoServer<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span> value <span class="token operator">=</span> <span class="token string">"/socket.io/"</span><span class="token punctuation">,</span> method <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token class-name">RequestMethod</span><span class="token punctuation">.</span>GET<span class="token punctuation">,</span> <span class="token class-name">RequestMethod</span><span class="token punctuation">.</span>POST<span class="token punctuation">,</span> <span class="token class-name">RequestMethod</span><span class="token punctuation">.</span>OPTIONS<span class="token punctuation">}</span><span class="token punctuation">,</span> headers <span class="token operator">=</span> <span class="token string">"Connection!=Upgrade"</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">httpHandler</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpServletResponse</span> response<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> mEngineIoServer<span class="token punctuation">.</span><span class="token function">handleRequest</span><span class="token punctuation">(</span>request<span class="token punctuation">,</span> response<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* HandshakeInterceptor */</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">beforeHandshake</span><span class="token punctuation">(</span><span class="token class-name">ServerHttpRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">ServerHttpResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">WebSocketHandler</span> wsHandler<span class="token punctuation">,</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">></span></span> attributes<span class="token punctuation">)</span> <span class="token punctuation">{</span> attributes<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>ATTRIBUTE_ENGINE_IO_QUERY<span class="token punctuation">,</span> request<span class="token punctuation">.</span><span class="token function">getURI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> attributes<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>ATTRIBUTE_ENGINE_IO_HEADERS<span class="token punctuation">,</span> request<span class="token punctuation">.</span><span class="token function">getHeaders</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">afterHandshake</span><span class="token punctuation">(</span><span class="token class-name">ServerHttpRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">ServerHttpResponse</span> response<span class="token punctuation">,</span> <span class="token class-name">WebSocketHandler</span> wsHandler<span class="token punctuation">,</span> <span class="token class-name">Exception</span> exception<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token comment">/* WebSocketHandler */</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">supportsPartialMessages</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">afterConnectionEstablished</span><span class="token punctuation">(</span><span class="token class-name">WebSocketSession</span> webSocketSession<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">final</span> <span class="token class-name">EngineIoSpringWebSocket</span> webSocket <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EngineIoSpringWebSocket</span><span class="token punctuation">(</span>webSocketSession<span class="token punctuation">)</span><span class="token punctuation">;</span> webSocketSession<span class="token punctuation">.</span><span class="token function">getAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>ATTRIBUTE_ENGINE_IO_BRIDGE<span class="token punctuation">,</span> webSocket<span class="token punctuation">)</span><span class="token punctuation">;</span> mEngineIoServer<span class="token punctuation">.</span><span class="token function">handleWebSocket</span><span class="token punctuation">(</span>webSocket<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">afterConnectionClosed</span><span class="token punctuation">(</span><span class="token class-name">WebSocketSession</span> webSocketSession<span class="token punctuation">,</span> <span class="token class-name">CloseStatus</span> closeStatus<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">EngineIoSpringWebSocket</span><span class="token punctuation">)</span>webSocketSession<span class="token punctuation">.</span><span class="token function">getAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>ATTRIBUTE_ENGINE_IO_BRIDGE<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">afterConnectionClosed</span><span class="token punctuation">(</span>closeStatus<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handleMessage</span><span class="token punctuation">(</span><span class="token class-name">WebSocketSession</span> webSocketSession<span class="token punctuation">,</span> <span class="token class-name">WebSocketMessage</span><span class="token generics"><span class="token punctuation"><</span><span class="token operator">?</span><span class="token punctuation">></span></span> webSocketMessage<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">EngineIoSpringWebSocket</span><span class="token punctuation">)</span>webSocketSession<span class="token punctuation">.</span><span class="token function">getAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>ATTRIBUTE_ENGINE_IO_BRIDGE<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">handleMessage</span><span class="token punctuation">(</span>webSocketMessage<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">handleTransportError</span><span class="token punctuation">(</span><span class="token class-name">WebSocketSession</span> webSocketSession<span class="token punctuation">,</span> <span class="token class-name">Throwable</span> throwable<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">EngineIoSpringWebSocket</span><span class="token punctuation">)</span>webSocketSession<span class="token punctuation">.</span><span class="token function">getAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>ATTRIBUTE_ENGINE_IO_BRIDGE<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">handleTransportError</span><span class="token punctuation">(</span>throwable<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">class</span> <span class="token class-name">EngineIoSpringWebSocket</span> <span class="token keyword">extends</span> <span class="token class-name">EngineIoWebSocket</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">WebSocketSession</span> mSession<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">></span></span> mQuery<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">List</span><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span><span class="token punctuation">></span></span> mHeaders<span class="token punctuation">;</span> <span class="token class-name">EngineIoSpringWebSocket</span><span class="token punctuation">(</span><span class="token class-name">WebSocketSession</span> session<span class="token punctuation">)</span> <span class="token punctuation">{</span> mSession <span class="token operator">=</span> session<span class="token punctuation">;</span> <span class="token keyword">final</span> <span class="token class-name">String</span> queryString <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">)</span>mSession<span class="token punctuation">.</span><span class="token function">getAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>ATTRIBUTE_ENGINE_IO_QUERY<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>queryString <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mQuery <span class="token operator">=</span> <span class="token class-name">ParseQS</span><span class="token punctuation">.</span><span class="token function">decode</span><span class="token punctuation">(</span>queryString<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> mQuery <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation"><</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span>mHeaders <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">Map</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">List</span><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span><span class="token punctuation">></span></span><span class="token punctuation">)</span> mSession<span class="token punctuation">.</span><span class="token function">getAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>ATTRIBUTE_ENGINE_IO_HEADERS<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/* EngineIoWebSocket */</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">></span></span> <span class="token function">getQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> mQuery<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">List</span><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token function">getConnectionHeaders</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> mHeaders<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">write</span><span class="token punctuation">(</span><span class="token class-name">String</span> message<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> mSession<span class="token punctuation">.</span><span class="token function">sendMessage</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">TextMessage</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">write</span><span class="token punctuation">(</span><span class="token keyword">byte</span><span class="token punctuation">[</span><span class="token punctuation">]</span> message<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">IOException</span> <span class="token punctuation">{</span> mSession<span class="token punctuation">.</span><span class="token function">sendMessage</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">BinaryMessage</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> mSession<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">IOException</span> ignore<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">/* WebSocketHandler */</span> <span class="token keyword">void</span> <span class="token function">afterConnectionClosed</span><span class="token punctuation">(</span><span class="token class-name">CloseStatus</span> closeStatus<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">"close"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">void</span> <span class="token function">handleMessage</span><span class="token punctuation">(</span><span class="token class-name">WebSocketMessage</span><span class="token generics"><span class="token punctuation"><</span><span class="token operator">?</span><span class="token punctuation">></span></span> message<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>message<span class="token punctuation">.</span><span class="token function">getPayload</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">instanceof</span> <span class="token class-name">String</span> <span class="token operator">||</span> message<span class="token punctuation">.</span><span class="token function">getPayload</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">instanceof</span> <span class="token keyword">byte</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">"message"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">Object</span><span class="token punctuation">)</span> message<span class="token punctuation">.</span><span class="token function">getPayload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">RuntimeException</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span> <span class="token string">"Invalid message type received: %s. Expected String or byte[]."</span><span class="token punctuation">,</span> message<span class="token punctuation">.</span><span class="token function">getPayload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">void</span> <span class="token function">handleTransportError</span><span class="token punctuation">(</span><span class="token class-name">Throwable</span> exception<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">"error"</span><span class="token punctuation">,</span> <span class="token string">"write error"</span><span class="token punctuation">,</span> exception<span class="token punctuation">.</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Client
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <span class="token doctype"><span class="token punctuation"><!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>title</span><span class="token punctuation">></span></span>Socket io client<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdn.socket.io/4.4.1/socket.io.min.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"> <span class="token keyword">const</span> socket <span class="token operator">=</span> <span class="token function">io</span><span class="token punctuation">(</span><span class="token string">'/mynamespace'</span><span class="token punctuation">)</span> socket<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">arg</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'connected'</span><span class="token punctuation">,</span> arg<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> socket<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'disconnect'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'disconnect'</span><span class="token punctuation">,</span> socket<span class="token punctuation">.</span>id<span class="token punctuation">)</span> <span class="token comment">// undefined</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">function</span> <span class="token function">submit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> txt <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'input'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>value socket<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">'message'</span><span class="token punctuation">,</span> txt<span class="token punctuation">)</span> <span class="token punctuation">}</span> </span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>input<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token special-attr"><span class="token attr-name">onclick</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript"><span class="token function">submit</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>Submit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>html</span><span class="token punctuation">></span></span> |
Và đây là thành quả.
github src: https://github.com/huyvu8051/springboot-socketio
Nhanh gọn lẹ đúng không nào, nếu có bất cứ câu hỏi nào plz leave comments.