springboot 整合 websocket实现在线聊天和消息通知

    技术2025-05-26  48

    一、内容一览

    本文由下文改进而来:https://blog.csdn.net/qq_41463655/article/details/92410518

    适合做简易聊天室,多聊天室,发送接收消息可添加分组id 适合做及时消息通知

    聊天页面,比较简陋

    另外提供 WebSocketController web接口

    API一览

    发送消息/通知接口API

    代码结构

    二、代码部分

    1、添加maven 依赖

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

    2、dto 创建 SendMsgDTO

    package com.ws.ldy.common.websocket.model.dto; import com.ws.ldy.base.convert.Convert; import lombok.Data; /*** * TODO websocket客服端-发送消息-入参参数 * @author 王松 * @mail 1720696548@qq.com * @date 2020/6/30 0030 18:24 */ @Data public class SendMsgDTO extends Convert { /** * 接收人用户Id (目标ID,逗号分隔) (所有人使用-ALL) */ private String to; /** * 发送内容 */ private String content; /** * @param to 接收人用户Id (目标ID,逗号分隔) (所有人使用-ALL) * @param content 发送内容 */ public SendMsgDTO(String to, String content) { this.to = to; this.content = content; } public SendMsgDTO() { } }

    3、entity/ 创建 OnlineUser

    package com.ws.ldy.common.websocket.model.entity; import com.ws.ldy.base.convert.Convert; import com.ws.ldy.common.utils.LocalDateTimeUtils; import lombok.AllArgsConstructor; import lombok.Data; import javax.websocket.Session; import java.time.LocalDateTime; /*** * TODO 当前在线列表信息 * @author 王松 * @mail 1720696548@qq.com * @date 2020/7/1 0001 11:58 */ @Data @AllArgsConstructor public class OnlineUser extends Convert { /** * 用户ID */ private String userId; /** * 用户名称 */ private String username; /** * 用户会话 (使用该对象进行消息发送) */ private Session session; /** * 连接时间 */ private String createTime; /** * @param userId 用户id * @param username 用户名称 * @param session 用户session 回话信息 */ public OnlineUser(String userId, String username, Session session) { this.userId = userId; this.username = username; this.session = session; this.createTime = LocalDateTimeUtils.parse(LocalDateTime.now()); } }

    4、vo/ 创建 OnlineUserVO

    package com.ws.ldy.common.websocket.model.vo; import com.ws.ldy.base.convert.Convert; import lombok.Data; /** * TODO 在线列表信息返回 */ @Data public class OnlineUserVO extends Convert { /** * 用户ID */ private String userId; /** * 用户名称 */ private String username; /** * 连接时间 */ private String createTime; }

    5、vo/ 创建 SendMsgVO (发送消息的所有内容)

    package com.ws.ldy.common.websocket.model.vo; import com.ws.ldy.base.convert.Convert; import com.ws.ldy.common.websocket.service.impl.WebsocketServiceImpl; import com.ws.ldy.common.utils.LocalDateTimeUtils; import lombok.Data; import java.time.LocalDateTime; /** * TODO websocket客户端-接收端-返回参数 * * @author 王松 * @mail 1720696548@qq.com * @date 2020/6/30 0030 18:24 */ @Data public class SendMsgVO extends Convert { /** * 消息类型(1-上线通知 2-下线通知 3-在线名单通知 4-代表普通消息通知 ) */ private Integer mesType; /** * 发送人用户Id(来源Id,上线为上线线人的用户Id) */ private String from; /** * 发送人用户名( 上下线为上线线人的用户名) */ private String username; /** * 接收人用户Id (目标ID,逗号分隔) (所有人使用-ALL,包括自己在内也能接收) */ private String to; /** * 发送内容 */ private String content; /** * 扩展消息字段(json) */ private String extras; /** * 当前在线人数 */ private Integer onlineNum; /** * 消息创建时间(YYYY-MM-DD ) */ private String createTime; // /** // * 消息类型,int类型(0:text、1:image、2:voice、3:vedio、4:music、5:news) // */ // private Integer msgType; /** * @param mesType 消息类型(1-上线通知 2-下线通知 3-在线名单通知 4-代表普通消息通知 ) * @param from 发送人Id(来源Id),上下线为上线人的用户id * @param username 发送人姓名username,上下线为上线人的用户名 * @param to 接收人Id(目标ID,逗号分隔,所有人使用-ALL) * @param content 发送消息内容 * @param extras 发送消息扩展字段 */ public SendMsgVO(Integer mesType, String from, String username, String to, String content, String extras) { this.mesType = mesType; this.from = from; this.username = username; this.to = to; this.content = content; this.extras = extras; this.onlineNum = WebsocketServiceImpl.onlineNumber.intValue(); this.createTime = LocalDateTimeUtils.parse(LocalDateTime.now()); } }

    6、WebsocketService 接口

    package com.ws.ldy.common.websocket.service; import com.ws.ldy.common.websocket.model.vo.OnlineUserVO; import javax.websocket.*; import javax.websocket.server.PathParam; import java.util.List; /** * TODO websocket 监听类(连接,断点,消息发送等) * <p> * /websocket/{userId}/{username} = /websocket/用户Id/用户名 来连接websocket,该参数会带到每一个监听方法中 * </P> */ public interface WebsocketService { //================================================================================ //================================================================================ //=============================== 监听方法 ======================================= //================================================================================ //================================================================================ /** * TODO 监听连接(有用户连接,立马到来执行这个方法),session 发生变化 * * @param userId 用户id * @param username 用户名 * @param session 当前用户会话 * @return void * @date 2020/6/30 0030 9:28 */ public void onOpen(@PathParam("userId") String userId, @PathParam("username") String username, Session session); /** * TODO 监听断开连接(有用户退出,会立马到来执行这个方法) * * @param userId 用户id * @param username 用户名 * @param session 当前用户会话 */ public void onClose(@PathParam("userId") String userId, @PathParam("username") String username, Session session); /** * TODO 异常停止 * * @param userId 用户id * @param username 用户名 * @param session 当前用户会话 * @param error 异常信息 */ public void onError(@PathParam("userId") String userId, @PathParam("username") String username, Session session, Throwable error); /** * TODO 监听消息发送(收到客户端的消息立即执行) * * @param userId 用户id * @param username 用户名 * @param message 传递的消息内容, json数据( to=接收人用户Id (目标ID,逗号分隔) || content=内容) * @param session 当前用户会话 * * <p> * // 前端发送内容格式 * .... * // 拼接参数 * let message = { "content": content, "to": to }; * // 发送数据 * webSocket.send(JSON.stringify(message)); * .... * </P> */ public void onMessage(@PathParam("userId") String userId, @PathParam("username") String username, String message, Session session); //================================================================================ //================================================================================ //======================= service方法(http接口调用操作) ============================ //================================================================================ //================================================================================ /** * 获取当前在线人数 * * @return */ public Integer getOnlineCount(); /** * 获取当前在线用户列表 * * @return */ public List<OnlineUserVO> getOnlineUsersList(); /** * 发送消息 * * @param form 发送人id * @param username 发送人用户名 * @param to 接收人id(多个逗号分隔) * @param content 发送内容 * @param extras 扩暂发送内容 * @return */ public List<OnlineUserVO> send(String form, String username, String to, String content, String extras); }

    7、WebsocketServiceImpl 接口实现( 重点)

    package com.ws.ldy.common.websocket.service.impl; import com.alibaba.fastjson.JSON; import com.ws.ldy.common.utils.JsonUtils; import com.ws.ldy.common.websocket.model.dto.SendMsgDTO; import com.ws.ldy.common.websocket.model.entity.OnlineUser; import com.ws.ldy.common.websocket.model.vo.OnlineUserVO; import com.ws.ldy.common.websocket.model.vo.SendMsgVO; import com.ws.ldy.common.websocket.service.WebsocketService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; /** * TODO websocket 监听类(连接,断点,消息发送等) * <p> * /websocket/{userId}/{username} = /websocket/用户Id/用户名 来连接websocket,该参数会带到每一个监听方法中 * </P> * * @ServerEndpoint: socket链接地址 */ @ServerEndpoint("/websocket/{userId}/{username}") @Service @Slf4j public class WebsocketServiceImpl implements WebsocketService { /** * 在线人数 //使用原子类AtomicInteger, ---> static并发会产生线程安全问题, //public static Integer onlineNumber = 0; */ public static AtomicInteger onlineNumber = new AtomicInteger(0); /** * 所有用户信息(session + userId + username + createTime --> 以用户的id为key, 通过用户key来获取用户session进行消息发送) */ public static Map<String, OnlineUser> clients = new ConcurrentHashMap<>(); //================================================================================ //================================================================================ //=============================== 监听方法 ======================================= //================================================================================ //================================================================================ /** * TODO 监听连接(有用户连接,立马到来执行这个方法),session 发生变化 */ @OnOpen public void onOpen(@PathParam("userId") String userId, @PathParam("username") String username, Session session) { // 自增1 onlineNumber.getAndIncrement(); // 保存新用户id,用户名,session会话,登录时间 clients.put(userId, new OnlineUser(userId, username, session)); // 告诉所有人,我上线了 String content = "系统消息:" + username + " 上线了"; this.send(new SendMsgVO(1, userId, username, "ALL", content, null)); // 给自己发一条消息:告诉自己现在都有谁在线 this.send(new SendMsgVO(3, userId, username, userId, JSON.toJSONString(getOnlineUsers()), null)); log.info("有新连接加入!sessionId:{} userId:{} userName:{} 当前在线人数:{}", session.getId(), userId, username, onlineNumber); } /** * TODO 监听断开连接(有用户退出,会立马到来执行这个方法) */ @OnClose public void onClose(@PathParam("userId") String userId, @PathParam("username") String username, Session session) { // 自减1 onlineNumber.getAndDecrement(); // 所有在线用户中去除下线用户 clients.remove(userId); // 告诉所有人,我下线了 String content = "系统消息:" + username + " 下线了"; this.send(new SendMsgVO(2, userId, username, "ALL", content, null)); // 日志 log.info(username + ":已离线! 当前在线人数" + onlineNumber); } /** * TODO 异常停止 */ @OnError public void onError(@PathParam("userId") String userId, @PathParam("username") String username, Session session, Throwable error) { error.printStackTrace(); log.info("服务端发生了错误" + error.getMessage()); } /** * TODO 监听消息发送(收到客户端的消息立即执行) */ @OnMessage public void onMessage(@PathParam("userId") String userId, @PathParam("username") String username, String message, Session session) { log.info("服务器接收到发送消息请求,发送人id={},用户名={}, 接收发送消息={}", userId, username, message); // 请求参数(接收人+发送内容) SendMsgDTO sendMsgDTO = JsonUtils.parseEntity(message, SendMsgDTO.class); // 发送消息 this.send(new SendMsgVO(4, userId, username, sendMsgDTO.getTo(), sendMsgDTO.getContent(), null)); } /** * 消息发送( 遍历用户Id , 在通过sendMsg方法发送消息) * * @param sendMsg:消息内容 */ private void send(SendMsgVO sendMsg) { if ("ALL".equals(sendMsg.getTo()) || "all".equals(sendMsg.getTo())) { // 发送消息给所有人 Set<String> userIds = clients.keySet(); for (String userId : userIds) { this.sendMsg(userId, sendMsg); } } else { //发送消息给指定人 String[] userIds = sendMsg.getTo().split(","); for (String userId : userIds) { this.sendMsg(userId, sendMsg); } } } /** * 消息发送(最后发送, 在send方法中循环用户Id 列表依次发送消息给指定人) * <p> * // 消息发送(同步:getBasicRemote 异步:getAsyncRemote) * </P> * * @param userId 消息接收人ID , onlineUsers 的 key * @param sendMsg 消息内容 */ private void sendMsg(String userId, SendMsgVO sendMsg) { // 判断用户是否在线, 在线发送消息推送 if (clients.containsKey(userId)) { try { clients.get(userId).getSession().getBasicRemote().sendText(JSON.toJSONString(sendMsg)); } catch (IOException e) { e.printStackTrace(); log.info(userId, sendMsg.getUsername() + "上线的时候通知所有人发生了错误"); } } } /** * 获取当前在线列表 * <p> * 获取当前在线列表, 把onlineUsers 转到 OnlineUsersVO返回 * </p> * * @return */ public synchronized List<OnlineUserVO> getOnlineUsers() { List<OnlineUserVO> onlineUsersVOList = new ArrayList<>(); for (OnlineUser onlineUsers : clients.values()) { onlineUsersVOList.add(onlineUsers.convert(OnlineUserVO.class)); } return onlineUsersVOList; } //================================================================================ //================================================================================ //======================= service方法(http接口调用操作) ============================ //================================================================================ //================================================================================ /** * 获取当前在线人数 * * @return */ public Integer getOnlineCount() { return onlineNumber.get(); } /** * 获取当前在线用户信息 * * @return */ public List<OnlineUserVO> getOnlineUsersList() { return getOnlineUsers(); } /** * 发送消息 (单向通知发送,不可回复) * * @param form 发送人id * @param username 发送人用户名 * @param to 接收人id(多个逗号分隔) * @param content 发送内容 * @param content 发送内容 * @param content 扩暂发送内容 * @return */ public List<OnlineUserVO> send(String form, String username, String to, String content, String extras) { // 发送消息 this.send(new SendMsgVO(4, form, username, to, content, extras)); return getOnlineUsers(); } }

    8、WebsocketController web-Api 接口方法

    package com.ws.ldy.base.controller; import com.ws.ldy.common.result.Result; import com.ws.ldy.common.result.ResultEnum; import com.ws.ldy.common.websocket.model.vo.OnlineUserVO; import com.ws.ldy.common.websocket.service.WebsocketService; import com.ws.ldy.config.error.ErrorException; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * websocket类 * * @ServerEndpoint: socket链接地址 */ @Api(value = "WebSocketController", tags = "websocket 相关通知/聊天") @RequestMapping("/websocket") @RestController @Slf4j public class WebSocketController { /** * websocket ip 或域名 */ @Value("${websocket.ip}") private String ip; /** * websocket 端口号 */ @Value("${websocket.port}") private String port; /** * websocket接口 */ @Value("${websocket.interfaceName}") private String interfaceName; /** * TODO 获取webSocket 连接地址, // 实际情况根据用户 token获取用户信息返回 * 获取socket地址 * 获取用户名 * 获取用户Id */ @RequestMapping(value = "/getPath", method = RequestMethod.GET) @ApiOperation("游客登录获取websocket连接地址") public Result<Map<String, String>> getPath() { // 配置检查 if (StringUtils.isBlank(ip) || StringUtils.isBlank(port) || StringUtils.isBlank(interfaceName)) { throw new ErrorException(ResultEnum.SYS_SOCKET_CONFIG_ERROR); } // 随机用户名 String username = "游客:" + new SimpleDateFormat("ssSSS").format(new Date()); // 随机用户id String userId = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()); // 连接地址, // "ws://192.168.0.154:9049/websocket/1/张三" String path = "ws://" + ip + ":" + port + interfaceName + "/" + userId + "/" + username; log.info("websocket请求地址:" + path); //返回参数 Map<String, String> map = new HashMap<>(); map.put("path", path); map.put("userId", userId); map.put("username", username); return Result.success(map); } // websocket 逻辑代码 @Autowired private WebsocketService websocketService; /** * TODO 发送消息 */ @RequestMapping(value = "/send", method = RequestMethod.POST) @ApiOperation("发送消息") @ApiImplicitParams({ @ApiImplicitParam(name = "form", value = "发送人Id", required = true), @ApiImplicitParam(name = "username", value = "发送人用户名", required = true), @ApiImplicitParam(name = "to", value = "接收人Id, 全部为ALL", required = true), @ApiImplicitParam(name = "content", value = "发送内容", required = true), @ApiImplicitParam(name = "extras", value = "附加发送内容", required = true) }) public Result<Void> send(String form, String username, String to, String content, String extras) { websocketService.send(form, username, to, content, extras); return Result.success(); } /** * TODO 获取当前在线人数 */ @RequestMapping(value = "/getOnlineCount", method = RequestMethod.GET) @ApiOperation("发送消息") public Result<Integer> getOnlineCount() { Integer onlineCount = websocketService.getOnlineCount(); return Result.success(onlineCount); } @RequestMapping(value = "/getOnlineUsersList", method = RequestMethod.GET) @ApiOperation("获取当前在线用户列表") public Result<List<OnlineUserVO>> getOnlineUsersList() { return Result.success(websocketService.getOnlineUsersList()); } }

    9、yml 创建websocket配置

    ## websocket 配置 websocket: # websocket 服务器部署地址的ip或者域名 --> 本地可以使用127.0.0.1 || localhost ip: 127.0.0.1 # websocket 服务器端口,获取当前服务器端口 port: ${server.port} # websocket 连接接口, WebsocketServiceImpl的 @ServerEndpoint 内参数 interfaceName: /websocket

    10、最后别忘了 WebSocketConfig 配置

    /** * TODO WebSocket 配置类 * @author 王松 * @mail 1720696548@qq.com * @date 2020/6/30 0030 9:26 */ @Configuration public class WebSocketConfig { /** * 服务器节点 * <p> * 如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理 * * @return */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }

    11、前端页面html

    <!DOCTYPE html> <html xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>websocket</title> <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js"></script> <script src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script> <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script> <script th:src="@{/js/app.js}"></script> </head> <css> </css> <style> /* overflow-y :auto;overflow :auto; 宽高自适应滚动条 */ /* 群聊*/ .quLiao { width: 80%; height: 300px; background-color: papayawhip; float: left; overflow-y: auto; overflow: auto; } /* 私聊*/ .siLiao { width: 80%; height: 300px; background-color: papayawhip; float: left; overflow-y: auto; overflow: auto; } /*在线列表*/ .zxList { width: 20%; background-color: #F2F2F2; float: left; overflow-y: auto; overflow: auto; } </style> <body> <br> <span class="quLiao" id="quLiao"> <li style="text-align: center">群聊信息</li> <!-- <li style="text-align: right">靠右</li> <li style="text-align: left" >靠左</li>--> </span> <span class="zxList" id="zxList"> <li style="text-align: center">在线列表</li> </span> <!-- 消息输入框 --> <textarea id="text" placeholder="请输入内容-发送消息[Ctrl+回车键]" rows="3%" cols="60%"></textarea> <td>消息发送至:</td> <select id="to" size="1" style="width: 10%;height:30px"> <option value="ALL">所有人</option> <!-- ALL 为所有人 --> </select> <input onclick="send()" type="button" value="发送"> <div class="siLiao" id="siLiao"> <li style="text-align: center">私聊信息</li> <!-- <li style="text-align: right">靠右</li> <li style="text-align: left" >靠左</li>--> </div> <br> <br> <!-- =============================================================================== --> </body> <script type="text/javascript"> // 获取socket连接地址,连接地址url中自带登录用户的账号信息,前端无需关心 let JsonData = ajaxGet(path + "/websocket/getPath"); // let socketPath = JsonData.data.path; //连接地址 let formUserId = JsonData.data.userId; //用户Id let formUsername = JsonData.data.username; //用户名 let zxList = $("#zxList"); //在线列表 let quLiao = $("#quLiao"); //群聊 let siLiao = $("#siLiao"); //私聊 let toList = $("#to"); //消息接收人select选择框 let webSocket; // var commWebSocket; http: if ("WebSocket" in window) { // 连接地址:后端获取 websocket = new WebSocket(socketPath); // 如: "ws://192.168.0.154:9049/websocket/张三/1" // 连通成功的监听 websocket.onopen = function () { quLiao.html(quLiao.html() + " <li style='text-align: center'>系统消息:[登陆成功]</li>") }; // 接收后台服务端的消息监听 websocket.onmessage = function (evt) { let received_msg = evt.data; // 接收到的数据 let obj = JSON.parse(received_msg); // json数据 let mesType = obj.mesType; // 数据类型(1上线/2下线/3在线名单/4发信息) let from = obj.from; // 来源Id,上下线时为上下线的用户id let username = obj.username; // 来源用户,上下线时为上下线的用户名 let to = obj.to; // 目标Id(接收人用户Id,逗号分隔,所有人时为-ALL)) let content = obj.content; // 内容 let extras = obj.extras; // 扩展内容(json) let onlineNum = obj.onlineNum; // 在线人数 let createTime = obj.createTime; // 消息时间 //alert(JSON.stringify(received_msg)); // 上线通知+在线列表刷新 if (mesType === 1) { // 群聊信息时上线 quLiao.html(quLiao.html() + " <li style='text-align: center;color: #00FF00'>" + content + " </li>"); // 在线列表(id=用户id,用于下线删除) zxList.html(zxList.html() + " <li id='" + from + "' style='text-align: left'>---" + username + "&nbsp;&nbsp;&nbsp;&nbsp;" + createTime + "</li>"); // 在线人选择框(optionId为了下线通知移除) toList.html(toList.html() + "<option id='option" + from + "' value='" + from + "'>" + username + "</option> ") } // 下线通知+在线列表刷新 else if (mesType === 2) { // 群聊信息暂时下线 quLiao.html(quLiao.html() + " <li style='text-align: center;color: red'>" + content + " </li>"); // 在线列表删除下线人 $("#" + from).remove(); // 在线人选择框移除下线人 $("#option" + from).remove(); } // 在线列表通知(自己登录时给自己发送) else if (mesType === 3) { zxList.html(""); toList.html("<option value='ALL'>所有人</option>"); // let userList = JSON.parse(content); for (let i = 0; i < userList.length; i++) { let userId = userList[i].userId; // 用户id let username = userList[i].username; // 用户名 let createTime = userList[i].createTime; // 用户登录时间 // alert(userList[i].username) if (userId !== from || userId !== formUserId) { // 在线列表(id=用户id,用于下线删除) zxList.html(zxList.html() + " <li id='" + userId + "' style='text-align: left'>---" + username + "&nbsp;&nbsp;&nbsp;&nbsp;" + createTime + "</li>"); // 在线人选择框(optionId为了下线通知移除) --》 不展示自己 toList.html(toList.html() + "<option id='option" + userId + "' value='" + userId + "'>" + username + "</option> ") } else { // 在线列表(id=用户id,用于下线删除) zxList.html(zxList.html() + " <li id='" + userId + "' style='text-align: left'>---" + username + " (自己)&nbsp;&nbsp;&nbsp;&nbsp;" + createTime + "</li>"); } } } // 信息接收通知 else if (mesType === 4) { if (to === "ALL") { // 群聊 // 判断是否为自己的消息,(自己 ==> 发送方=接收方 || 发送方是自己) if (to === from || formUserId === from) { //自己右边展示 quLiao.html(quLiao.html() + " <li style='text-align: right;'>" + content + " <--" + username + " </li>"); } else { //左边展示 quLiao.html(quLiao.html() + " <li style='text-align: left;'>" + username + "--> " + content + " </li>"); } } else { // 私聊 // 判断是否为自己的消息,(自己 ==> 发送方=接收方 || 发送方是自己) if (to === from || formUserId === from) { //自己右边展示 siLiao.html(siLiao.html() + " <li style='text-align: right;'>" + content + " <--" + username + " </li>"); } else { //左边展示 siLiao.html(siLiao.html() + " <li style='text-align: left;'>" + username + "--> " + content + " </li>"); } } } }; // 连接关闭的回调事件 websocket.onclose = function () { console.log("连接已关闭..."); document.getElementById('message').innerHTML += '连接已经关闭....' + '<br/>'; }; } else { // 浏览器不支持 WebSocket alert("您的浏览器不支持 WebSocket!"); } /** * TODO 关闭websocket 连接 --> 关闭窗口也会自动断开连接 */ function closeWebSocket() { //直接关闭websocket的连接 websocket.close(); } /** * TODO 按下Ctrl + 回车 发送消息 */ $(document).keyup(function (event) { //浏览器适应 if (event.ctrlKey && event.which == 13 || event.which == 10) { send(); } else if (event.shiftKey && event.which == 13 || event.which == 10) { send(); } }); /** * TODO 点击发送按钮发送消息 */ function send() { let to = $("#to").val(); // 接收数据人id let content = $("#text").val(); // 发送的数据 // 发送给指定人时,给自己也推送一个消息 if (to !== "ALL") { to = to + "," + formUserId; } // 参数拼接 let message = { "content": content, "to": to }; //发送数据 websocket.send(JSON.stringify(message)); $("#text").val(""); } </script> </html>

    重点还是在与html 的js中获取到参数如何处理参数,以及发送消息处理,到此可以先线上完成websocket 聊天功能了, 以及直接使用web-api 接口获取到在线人数, 直接所有发送消息Api 接口向聊天室发送任意消息

    本文到此结束,如果觉得有用,动动小手点赞或关注一下呗,将不定时持续更新更多的内容…,感谢大家的观看!

    Processed: 0.009, SQL: 9