SpringBoot--使用socket搭建聊天室
1、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、添加工具类
package com.example.demo.utils; import javax.websocket.RemoteEndpoint; import javax.websocket.Session; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public final class WebSocketUtils { /** * 模拟存储websocket session */ public static final Map<String, Session> LIVING_SESSION_CACHE = new ConcurrentHashMap(); public static void sendMessageAll(String message){ LIVING_SESSION_CACHE.forEach((sessionId,session) -> sendMessage(session,message)); } /** * 发送给指定用户 * @param session * @param message */ public static void sendMessage(Session session, String message){ if(session == null){ return; } final RemoteEndpoint.Basic basic = session.getBasicRemote(); if(basic == null){ return; } try { basic.sendText(message); }catch (Exception e){ e.printStackTrace(); } } }
3、添加服务站点
主要使用注解如下:
@ServerEndpoint:聊天室访问地址
@OnOpen: 建立 WebSocket 连接时触发
@OnMessage:客户端监听服务端事件,当服务端向客户端推送消息时会被监听到
@OnClose:关闭 WebSocket 连接时触发
@OnError:发生错误时触发
@GetMapping:接收消息请求地址
其中@ServerEndpoint 中的内容就是 WebSocket 协议的地址,其实仔细看会发现与 @RequestMapping 也是异曲同工的… HTTP 协议:http://localhost:8080/path WebSocket 协议:ws://localhost:8080/path
package com.example.demo.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import static com.example.demo.utils.WebSocketUtils.LIVING_SESSION_CACHE; import static com.example.demo.utils.WebSocketUtils.sendMessage; import static com.example.demo.utils.WebSocketUtils.sendMessageAll; @RestController @ServerEndpoint("/chat-room/{username}") public class SocketController { private static final Logger log = LoggerFactory.getLogger(SocketController.class); @OnOpen public void openSession(@PathParam("username") String name, Session session){ LIVING_SESSION_CACHE.put(name,session); String message = "欢迎用户["+ name + "]来到朦胧的夜聊天室"; 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_SESSION_CACHE.remove(username); //通知他人 sendMessageAll("用户["+username+"]已经离开朦胧的夜聊天室"); try { session.close(); }catch (Exception e){ e.printStackTrace(); } } @OnError public void onError(Session session,Throwable throwable){ try { session.close(); }catch (Exception 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_SESSION_CACHE.get(receive),"["+sender+"]:"+message); } }
4、添加聊天室html
此处注意一点,要添加引入jquery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>battcn websocket</title>
<script src="/jquery-3.4.1.min.js" ></script>
</head>
<body>
<label for="message_content">聊 天 室 </label><textarea id="message_content" readonly="readonly" cols="57" rows="10">
</textarea>
<br/>
<label for="in_user_name">用户姓名 </label><input id="in_user_name" value=""/>
<button id="btn_join">加入聊天室</button>
<button id="btn_exit">离开聊天室</button>
<br/><br/>
<label for="in_room_msg">群发消息 </label><input id="in_room_msg" value=""/>
<button id="btn_send_all">发送消息</button>
<br/><br/><br/>
好友聊天
<br/>
<label for="in_sender">发送者 </label><input id="in_sender" value=""/><br/>
<label for="in_receive">接受者 </label><input id="in_receive" value=""/><br/>
<label for="in_point_message">消息体 </label><input id="in_point_message" value=""/><button id="btn_send_point">发送消息</button>
</body>
<script type="text/javascript">
$(document).ready(function(){
var urlPrefix ='ws://localhost:8080/chat-room/';
var ws = null;
$('#btn_join').click(function(){
var username = $('#in_user_name').val();
var url = urlPrefix + username;
ws = new WebSocket(url);
ws.onopen = function () {
console.log("建立 websocket 连接...");
};
ws.onmessage = function(event){
//服务端发送的消息
$('#message_content').append(event.data+'\n');
};
ws.onclose = function(){
$('#message_content').append('用户['+username+'] 已经离开聊天室!');
console.log("关闭 websocket 连接...");
}
});
//客户端发送消息到服务器
$('#btn_send_all').click(function(){
var msg = $('#in_room_msg').val();
if(ws){
ws.send(msg);
}
});
// 退出聊天室
$('#btn_exit').click(function(){
if(ws){
ws.close();
}
});
$("#btn_send_point").click(function() {
var sender = $("#in_sender").val();
var receive = $("#in_receive").val();
var message = $("#in_point_message").val();
$.get("/chat-room/"+sender+"/to/"+receive+"?message="+message,function() {
alert("发送成功...")
})
})
})
</script>
</html>
5、主函数
@Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); }
6、添加入口方法
@GetMapping(value ="/sockethtml") public String sockethtml(){ return "lliaotianshi"; }
7、测试
http://localhost:8080/test/sockethtml

------------------------------------------------------------------
-----------------------------------------------------------
---------------------------------------------
朦胧的夜 留笔~~
-----------------------------------------------------------
---------------------------------------------
朦胧的夜 留笔~~

浙公网安备 33010602011771号