赞
踩
1、项目展示图
登录
登录成功
互动
2、websocket介绍
websocket是一种全双工的连接,即服务器和客户端之间建立了一次连接后,两者之间就会一直打开这个通道,就可以相互进行通信。相对于传统单双工的http请求,节省很多资源,不需要一直轮询服务器。
3、springboot代码(主要是写websocket相关的方法,比如创建连接事件,接收消息以及发送消息事件,关闭连接事件)
- package com.example.message.WebSocket;
-
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.gcp.basicproject.util.ParamUtil;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.context.ApplicationContext;
- import org.springframework.stereotype.Component;
-
- import javax.websocket.OnClose;
- import javax.websocket.OnMessage;
- import javax.websocket.OnOpen;
- import javax.websocket.Session;
- import javax.websocket.server.PathParam;
- import javax.websocket.server.ServerEndpoint;
- import java.io.IOException;
- import java.util.concurrent.ConcurrentHashMap;
-
- /**
- * @author Admin
- */
- @ServerEndpoint("/chat/{name}")
- @Component
- public class AllWebSocketService {
-
- static Logger log = LoggerFactory.getLogger(AllWebSocketService.class);
-
- private static int onlineCount = 0;
-
- private static ConcurrentHashMap<String,AllWebSocketService> webSocketServerMap = new ConcurrentHashMap<>();
-
- private Session session;
-
- private String name = "";
-
- private static ApplicationContext applicationContext;
-
- /**
- * 解决引入外部类方法
- * @param context
- */
- public static void setApplicationContext(ApplicationContext context){
- applicationContext = context;
- }
-
- /**
- * 建立连接
- * @param session
- * @param name
- */
- @OnOpen
- public void onOpen(Session session,@PathParam("name") String name){
- this.session = session;
- webSocketServerMap.put(name,this);
- this.name = name;
- addOnlineCount();
- log.info("用户连接:"+name+",当前在线人数为:"+getOnlineCount());
- try{
- sendMessage("进入聊天室成功");
- }catch (IOException e){
- log.error("用户:"+name+",连接失败!!");
- }
- }
-
- /**
- * 关闭连接
- */
- @OnClose
- public void onClose(){
- subOnlineCount();
- webSocketServerMap.remove(name);
- log.info("用户退出:"+name+",当前在线人数为:"+getOnlineCount());
- }
-
-
- @OnMessage
- public void onMessage(String message){
- log.info("用户消息:"+name+",报文:"+message);
- if(ParamUtil.notEmpty(message)){
- log.info(message);
- JSONObject jsonObject = JSON.parseObject(message);
- jsonObject.put("name",this.name);
- webSocketServerMap.forEach((u,m)->{
- if(name.contains(u)){
- return;
- }
- try {
- m.sendMessage(jsonObject.toJSONString());
- } catch (IOException e) {
- e.printStackTrace();
- }
- });
- }
- }
-
- /**
- * 服务器推送消息
- * @param message
- * @throws IOException
- */
- public void sendMessage(String message) throws IOException {
- this.session.getBasicRemote().sendText(message);
- }
-
-
- /**
- * 获取在线人数
- * @return
- */
- public static synchronized int getOnlineCount(){
- return onlineCount;
- }
-
- /**
- * 上线
- */
- public static synchronized void addOnlineCount(){
- AllWebSocketService.onlineCount++;
- }
-
- /**
- * 离线
- */
- public static synchronized void subOnlineCount(){
- AllWebSocketService.onlineCount--;
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
4、vue代码(主要是写连接本地的websocket,接收、发送和显示消息)
- <!-- 聊天室 -->
- <template>
- <h1>聊天室</h1>
- <el-scrollbar height="400px" style="border:1px solid #1813131f">
- <el-tag v-for="item in list" :key="item" class="scrollbar-demo-item" :style="`justify-content: ${item.type}`">{{
- item.name
- }}:{{ item.content }}</el-tag>
- </el-scrollbar>
- 发送消息:<el-input v-model="msg"></el-input>
- <el-button @click="sendMesage(msg)">发送消息</el-button>
- <el-button text @click="dialogFormVisible = true">登录</el-button>
-
- <el-dialog v-model="dialogFormVisible" title="登录">
- 请输入用户昵称:
- <el-input v-model="name" autocomplete="off" />
- <template #footer>
- <span class="dialog-footer">
- <el-button type="primary" @click="login()">确认</el-button>
- </span>
- </template>
- </el-dialog>
- <router-link to="/">返回首页</router-link>
- </template>
-
- <script>
- import { onBeforeUnmount, reactive, ref } from 'vue'
- import { ElMessage } from 'element-plus'
-
- export default {
- name: "chat",
- setup() {
- const list = reactive([]);
- let socket = null;
-
- // Websoket连接成功事件
- const websocketonopen = (res) => {
- ElMessage.success("WebSocket连接成功");
- };
- // Websoket接收消息事件
- const websocketonmessage = (res) => {
- if (res.data) {
- ElMessage.success("接收到消息:" + JSON.parse(res.data).content);
- message.content = JSON.parse(res.data).content;
- message.name = JSON.parse(res.data).name;
- message.type = 'left';
- list.push(JSON.parse(JSON.stringify(message)));
- console.log(list);
- }
- };
- // Websoket连接错误事件
- const websocketonerror = (res) => {
- ElMessage.error("连接错误");
- };
- // Websoket断开事件
- const websocketclose = (res) => {
- ElMessage.error("断开连接");
- };
-
- let message = reactive(
- {
- name: "",
- content: "",
- type: ''
- }
- );
- let msg = ref("");
- let name = ref("");
- const dialogFormVisible = ref(false);
-
- const sendMesage = (m) => {
- if (name.value == "") {
- ElMessage.warning("未登录,无法发送消息");
- } else {
- ElMessage.success("发送消息:" + m)
- message.content = m;
- message.name = name.value;
- message.type = 'right';
- socket.send(JSON.stringify(message));
- //解决message对象只有一个,push修改所有message对象的问题
- list.push(JSON.parse(JSON.stringify(message)));
- console.log(list);
- }
- }
- // 创建 websocket 的实例
- const createSocket = () => {
- const wsurl = "ws://localhost:8075/chat/" + name.value;
- socket = new WebSocket(wsurl);
- socket.onopen = websocketonopen;
- socket.onmessage = websocketonmessage;
- socket.onerror = websocketonerror;
- socket.onclose = websocketclose;
- };
- //登录聊天室
- const login = () => {
- console.log(name);
- createSocket();
- dialogFormVisible.value = false;
- }
-
- // 组件被销毁之前,清空 sock 对象
- onBeforeUnmount(() => {
- // 关闭连接
- websocketclose;
-
- // 销毁 websocket 实例对象
- socket = null;
- });
- //建立连接,创建websocket实例
-
- return {
- name,
- list,
- msg,
- message,
- dialogFormVisible,
- sendMesage,
- createSocket,
- login
- };
- },
- };
-
- </script>
-
- <style scoped>
- .read-the-docs {
- color: #888;
- }
-
- .scrollbar-demo-item {
- display: flex;
- align-items: center;
- height: 30px;
- margin: 10px;
- text-align: left;
- border-radius: 4px;
- }
- </style>
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。