欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 高考 > 使用WebSocket实现一个简易的聊天室

使用WebSocket实现一个简易的聊天室

2024/10/25 6:22:59 来源:https://blog.csdn.net/qq_51321722/article/details/141188014  浏览:    关键词:使用WebSocket实现一个简易的聊天室

我这里的框架是SpringBoot

首先,我们要有一个前端页面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"layout:decorate="layout">
<head><script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js" defer></script><meta charset="UTF-8"/><meta name="viewport"content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/><title>websocket</title>
</head>
<body>
<input type="text" placeholder="请输入您想显示的昵称" name="username" id="username" />
<button onclick="connection()">链接服务器</button>
<!--<button onclick="send()">发送数据到服务器</button>-->
<button onclick="closeSocket()">关闭连接</button>
<p style="border: 1px solid black;width: 680px;height: 500px" id="talkMsg"></p>
<input id="message"/><button id="sendBtn" onclick="send()">发送</button>
</body>
<script>let sock=""let username=""function connection(){username = $("#username").val()//ws是WebSocket协议sock = new WebSocket('ws://localhost:8080/v1/point/' + username);//WebSocket事件sock.onopen = () => {console.log("已经与服务器建立连接.")}sock.onmessage = (e) => {console.log("\n已获取服务器响应的数据.")console.log(e)document.getElementById("talkMsg").innerHTML = e.data}sock.onclose = () => {console.log("已关闭与服务器的连接.")}sock.onerror = (e) => {console.log("连接发生异常.")console.log(e)}}/*** 发送数据到服务端*/function send() {// sock.send(JSON.stringify({'message': ' hello world! '}))// sock.send(JSON.stringify({'message': document.getElementById("message").value }))if(document.getElementById("message").value===""){alert("抱歉,消息不能为空^_^")}else{var message = username + ":" +document.getElementById("message").valuesock.send(message)//发送完信息之后输入框变为空document.getElementById("message").value=""document.getElementById("talkMsg").innerHTML=""}}/*** 关闭当前用户与WebSocket的连接*/function closeSocket() {//代码只能是 1000,或者[3000, 4999]之间let code = 3000;let reason = "我想关闭连接!";sock.close(code, reason)}
</script>
</html>

其次,要有相关配置类以及Controller

配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration   //标明该类是配置类
public class WebSocketConfig {/*** @Bean 注解会把该方法的返回值当做一个JavaBean,存放在Spring上下文中,以供使用* ServerEndpointExporter类的作用是,会扫描所有的服务器端点,* 把带有  @ServerEndpoint 注解的所有类都添加进来* @return*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

Controller

import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;/*** 该类是用于ws的* value:当前 WebSocket 服务的访问(监听)地址*/
@Component  //生产对象,声明为类
@ServerEndpoint(value = "/v1/point/{username}")     //表明监听地址
public class EndPointController {//存储用户,通过一个Map来完成存储private static final Map<String,EndPointController> online = new ConcurrentHashMap<>();//发送数据是通过session对象实现的,那么就要给每个用户一个session对象private Session session;//记录所发出的信息private static StringBuffer stringBuffer = new StringBuffer();//以下方法都是被触发,而不是访问/*** 连接建立时被调用。*/@OnOpenpublic void onOpen(@PathParam("username") String username, Session session, EndpointConfig config) throws IOException {
//        System.out.println("连接已经建立.");this.session = session;     //等号之前的session指的是第24行的,后面的是该方法的online.put(username,this);//给前端的控制台返回数据
//        session.getBasicRemote().sendText(username+"已加入群聊");String message = username + "已加入群聊";stringBuffer.append(message + "<br/>");
//        broadcastAllUsers(stringBuffer.toString());}/*** 收到消息时被调用。* @param message 前端传递过来的消息。* @param session*/@OnMessagepublic void onMessage(String message, Session session) throws IOException {
//        System.out.println("收到了消息:" + message);//将消息推送到前端
//        session.getBasicRemote().sendText("谢谢,我收到了你的消息:" + message);stringBuffer.append(message);broadcastAllUsers(stringBuffer.toString());}/*** 连接关闭时被调用.** @param session* @param reason  关闭的理由*/@OnClosepublic void onClose(Session session, CloseReason reason) {System.out.println("连接已关闭,关闭理由:" + reason);}/*** 当连接发生异常时被调用** @param session* @param e*/@OnErrorpublic void onError(Session session, Throwable e) {System.out.println("连接发生异常:" + e.getMessage());e.printStackTrace();}//遍历map将数据发送给每个用户private void broadcastAllUsers(String message) throws IOException {Set<String> names = online.keySet();    //keySet返回所有key值列表for (String name : names) {EndPointController endPoint = online.get(name);//将数据发送给每一个人stringBuffer.setLength(0);stringBuffer.append(message+ "<br/>");endPoint.session.getBasicRemote().sendText(stringBuffer.toString());
//            System.out.println(stringBuffer.toString());}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com