SpringBoot
是为了简化Spring
应用的创建、运行、调试、部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖就可以轻易的搭建出一个 WEB 工程
Webscoket
对浏览器有一定的要求,所以使用之前要考虑兼容性的问题….
Webscoket
WebSocket
是 HTML5 新增的一种在单个 TCP 连接上进行全双工通讯的协议,与 HTTP 协议没有太大关系….
在 WebSocket API
中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
浏览器通过 JavaScript
向服务器发出建立 WebSocket
连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
当你获取 WebSocket
连接后,你可以通过 send()
方法来向服务器发送数据,并通过 onmessage()
事件来接收服务器返回的数据..
长连接
与 AJAX 轮训的方式差不多,但长连接不像 AJAX 轮训一样,而是采用的阻塞模型(一直打电话,没收到就不挂电话);客户端发起连接后,如果没消息,就一直不返回 Response 给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。
在没有 WebSocket
之前,大家常用的手段应该就是轮训了,比如每隔几秒发起一次请求,但这样带来的就是高性能开销,都知道一次 HTTP 响应是需要经过三次握手和四次挥手,远不如 TCP 长连接来的划算
WebSocket 事件
本章目标
利用 Spring Boot
与 WebSocke
打造 一对一 和 一对多 的在线聊天….
导入依赖
依赖 spring-boot-starter-websocket
…
1 2 3 4 5 6 7 8 9 10 |
|
属性配置
工具类
为了减少代码量,此处就不集成 Redis
、Mysql
之类的存储化依赖…
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 | package com.battcn.utils; import javax.websocket.RemoteEndpoint; import javax.websocket.Session; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author Levin * @since 2018/6/26 0026 */ public final class WebSocketUtils { /** * 模拟存储 websocket session 使用 */ public static final Map |
服务端点
@ServerEndpoint
中的内容就是 WebSocket
协议的地址,其实仔细看会发现与 @RequestMapping
也是异曲同工的…
- HTTP 协议:
http://localhost:8080/path
- WebSocket 协议:
ws://localhost:8080/path
@OnOpen
、@OnMessage
、@OnClose
、@OnError
注解与 WebSocket
中监听事件是相对应的…
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 | package com.battcn.websocket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import static com.battcn.utils.WebSocketUtils.LIVING_SESSIONS_CACHE; import static com.battcn.utils.WebSocketUtils.sendMessage; import static com.battcn.utils.WebSocketUtils.sendMessageAll; /** * 聊天室 * * @author Levin * @since 2018/6/26 0026 */ @RestController @ServerEndpoint("/chat-room/{username}") public class ChatRoomServerEndpoint { private static final Logger log = LoggerFactory.getLogger(ChatRoomServerEndpoint.class); @OnOpen public void openSession(@PathParam("username") String username, Session session) { LIVING_SESSIONS_CACHE.put(username, session); String message = "欢迎用户[" + username + "] 来到聊天室!"; log.info(message); sendMessageAll(message); } @OnMessage public void onMessage(@PathParam("username") String username, String message) { log.info(message); sendMessageAll("用户[" + username + "] : " + message); } @OnClose public void onClose(@PathParam("username") String username, Session session) { //当前的Session 移除 LIVING_SESSIONS_CACHE.remove(username); //并且通知其他人当前用户已经离开聊天室了 sendMessageAll("用户[" + username + "] 已经离开聊天室了!"); try { session.close(); } catch (IOException e) { e.printStackTrace(); } } @OnError public void onError(Session session, Throwable throwable) { try { session.close(); } catch (IOException e) { e.printStackTrace(); } throwable.printStackTrace(); } @GetMapping("/chat-room/{sender}/to/{receive}") public void onMessage(@PathVariable("sender") String sender, @PathVariable("receive") String receive, String message) { sendMessage(LIVING_SESSIONS_CACHE.get(receive), "[" + sender + "]" + "-> [" + receive + "] : " + message); } } |
聊天室 HTML
onopen
建立 WebSocket 连接时触发。message
客户端监听服务端事件,当服务端向客户端推送消息时会被监听到。error
WebSocket 发生错误时触发。close
关闭 WebSocket 连接时触发。
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 |
|