iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >SpringBoot整合WebSocket实现聊天室流程全解
  • 501
分享到

SpringBoot整合WebSocket实现聊天室流程全解

SpringBoot整合WebSocket实现聊天室SpringBootWebSocket聊天室 2023-01-04 12:01:53 501人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录什么是websocket WEBSocket通信模型为什么需要WebSocketWebsocket与Http的关系SpringBoot集成WebSocket什么是Web

什么是WebSocket 

WebSocket是一种在单个tcp连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket api中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

WebSocket通信模型

为什么需要WebSocket

http 通信是单向的,发送请求获取响应,没有请求也就没有响应。

简单理解:

  • HTTP 打电话:客户端问一句服务端答一句
  • WebSocket 打电话:双向对话

Websocket与http的关系

相同点:

  • 都是基于tcp的,都是可靠性传输协议
  • 都是应用层协议

不同点:

  • WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息
  • HTTP是单向的
  • WebSocket是需要浏览器和服务器握手进行建立连接的而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。

springBoot集成WebSocket

Maven依赖

		<dependency>  
           <groupId>org.springframework.boot</groupId>  
           <artifactId>spring-boot-starter-websocket</artifactId>  
       </dependency> 

WebSocketConfig

@Configuration  
public class WebSocketConfig {  
    @Bean  
    public ServerEndpointExporter serverEndpointExporter() {  
        return new ServerEndpointExporter();  
    }  
}

WebSocketService

@Slf4j
@Service
@ServerEndpoint(value = "/myService/{userId}")
public class WebSocketService {
    
    private static AtomicInteger onlineCount = new AtomicInteger(0);;
    
    private static ConcurrentHashMap<String,WebSocketService> webSocketMap = new ConcurrentHashMap<>();
    
    private static ConcurrentHashMap<String,Session> sessionMap = new ConcurrentHashMap<>();
    
    private Session session;
    private String userId = "";
    
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        if(webSocketMap.containsKey(userId) && sessionMap.containsKey(userId)){
            webSocketMap.remove(userId);
            sessionMap.remove(userId);
            sessionMap.put(userId,session);
            webSocketMap.put(userId,this);
        }else{
            webSocketMap.put(userId,this);
            sessionMap.put(userId,session);
            addOnlineCount();
        }
        log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());
    }
    
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            subOnlineCount();
        }
        log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
    }
    
    @OnMessage
    public void onMessage(String message, Session session) {
        this.session = session;
        log.info("收到客户端消息 -> {}",message);
        //服务端收到客户端的消息并推送给客户端
        sendMessage(message);
    }
    
    @OnError
    public void onError(Session session, Throwable error) {
       log.error(error.getMessage());
    }
    
    public void sendMessage(String message){
        try {
            Set<Map.Entry<String, Session>> entries = sessionMap.entrySet();
            for (Map.Entry<String, Session> next : entries) {
                Session session = next.getValue();
                session.getBasicRemote().sendText(this.userId + "说" + message);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }
    public static synchronized int getOnlineCount() {
        return onlineCount.get();
    }
    public static synchronized void addOnlineCount() {
        WebSocketService.onlineCount.getAndIncrement();
    }
    public static synchronized void subOnlineCount() {
        WebSocketService.onlineCount.getAndDecrement();
    }
}

WebSocket.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>websocket通讯</title>
</head>
<body>
	<p>userId:<input id="userId" name="userId" type="text" value="10"></p>
	<p>msg:<input id="contentText" name="contentText" type="text" value="hello websocket"></p>
	<p>操作:<button onclick="openSocket()">开启socket</button></p>
	<p>操作:<button onclick="sendMessage()">发送消息</button></p>
</body>
<script type="application/javascript">
    let socket;
    function openSocket() {
        if(socket != null){
            socket.close();
            socket = null;
        }
        let userId = document.getElementById('userId').value
        socket = new WebSocket("ws://localhost:9000/myService/"+userId);
        //打开事件
        socket.onopen = function() {
            console.log("websocket已打开");
        };
        //获得消息事件
        socket.onmessage = function(msg) {
            console.log(msg.data);
        };
        //关闭事件
        socket.onclose = function() {
            console.log("websocket已关闭");
        };
        //发生了错误事件
        socket.onerror = function() {
            console.log("websocket发生了错误");
        }
    }
    function sendMessage() {
        let contentText = document.getElementById('contentText').value
        socket.send(contentText);
    }
</script>
</html>

测试

到此这篇关于SpringBoot整合WebSocket实现聊天室流程全解的文章就介绍到这了,更多相关SpringBoot WebSocket聊天室内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: SpringBoot整合WebSocket实现聊天室流程全解

本文链接: https://www.lsjlt.com/news/176642.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作