socketio实现方式

一、后端实现

1.1、基本实现

  • 导入依赖
<dependency><groupId>com.corundumstudio.socketio</groupId><artifactId>netty-socketio</artifactId><version>1.7.11</version>
</dependency>
  • SocketIo配置

  • SocketIo启动

  • 消息实现类
SocketIoHandler

下面详细说明

后端大概就这些代码了,很简洁的,多的就没有。

1.2、消息处理类

  • 监听客户端连接

客户端连接成功是调用。

在方法上面打上 @OnConnect注解,表示监听连接情况,这个方法传入 SocketIOClient对象,获取连接这个客户端的信息。

这里最主要获取客户端的 sessionID和客户的唯一标识,其实这个sessionID就是一个 java.util.UUID对象,但是指定用户发送信息是需要用到,所以在这里就拿到它并保存到Map集合中。

这里我们做的不多,就是获取一个UUID和用户唯一标识。这些都是String类型的,如果用户量比较大的情况下,我们可以存入Redis中,不要存在这个Map集合了。

  • 监听客户端断开

客户端断开连接时调用。

在方法上打上 @OnDisconnect注解,表示监听客户端是否断开。同样需要 SocketIOClient对象,当客户端断开时可以获取到sessionID和用户唯一标识等客户端信息。但是我觉得只要获取到用户唯一标识就足够了,因为sessionID在连接成功就拿到并保存了的。

客户端断开了,获取到客户唯一标识并在保存客户端信息这里面删除,这里是保存在map集合中,那么就在这个集合中删除就OK。删除就标识不在线啦。

  • 监听客户端名为某个事件的信息

客户端代码应该是这样的。

socket.emit("事件名","参数数据")方法,是触发后端自定义消息事件的时候使用的

当事件名为 roomMessageSending这个时发送的数据就会在这里被调用,这里也可以获取到客户端的相关信息,和客户端传过来的数据。这个事件名是随便写的,数据也可以是其他形式的,比如对象 ,前端平时对象是怎么赋值的就怎么赋值。

  • 给指定的客户发送信息

关键就是这一句

// 获取对象
@Autowired
private SocketIOServer socketIOServer;socketIOServer.getClient(roomMap.get(roomId)).sendEvent(roomId, data) ;

roomMap.get(roomId)根据你要发送信息给哪个客户,那么就将这个客户的唯一标识穿过来,利用这个唯一标识就可以在Map集中获取sessionID,就是在连接成功时获取的那个UUID

sendEvent(roomId, data)roomId客户的唯一标识,data需要穿的数据,当然也可以是其他数据类型。

二、前端实现

安装 socket.io

npm install --save socket.io-client

  • 引入socket
import sio from "socket.io-client";
  • 注意这两个生命周期
  /*** 加载组件执行* 是数据挂载后的生命周期函数*/mounted() {this.connect();},/*** 关闭组件执行* 实例销毁后*/destroyed() {this.socketIoClient.close();},

mounted()数据已经挂在到模板中,这时执行 connect()这个方法,让socketIo的信息,并将这个对象保存,方便后面使用。

  • 完整代码
<template><div><h2 ref="SendMsg"><ul><li v-for="(item, index) in itemArr" :key="index">{{ item }}</li></ul></h2><input type="text" v-model="msg" /><button @click="sendMsg">发送</button></div>
</template> <script>
import sio from "socket.io-client";
export default {name: "HelloWorld",data() {return {socketIoClient: null,itemArr: ["欢迎来到WIM1000聊天室"],roomId: "WIM1000",msg: "",};},methods: {connect() {this.socketIoClient = sio.connect("http://192.168.124.7:9092?roomId=" + this.roomId);// 服务器连接成功调用this.socketIoClient.on("connect", function () {console.log("连接了服务器");});// 监听当前用户唯一标识的这个事件名,用户发送信息就靠这个事件名来接收。this.subscription();},subscription() {let vm = this;//   socket.on("事件名",匿名函数(服务器向客户端发送的数据))为监听服务器端的事件this.socketIoClient.on(this.roomId, function (data) {// 这是服务器端发送的信息console.log(data);vm.itemArr.push(data);});},sendMsg() {// socket.emit("事件名","参数数据")方法,是触发后端自定义消息事件的时候使用的,this.socketIoClient.emit("roomMessageSending", this.msg);},},/*** 加载组件执行* 是数据挂载后的生命周期函数*/mounted() {this.connect();},/*** 关闭组件执行* 实例销毁后*/destroyed() {this.socketIoClient.close();},
};
</script>

三、测试效果

  • 整个过程分析

this.socketIoClient.on(this.roomId, function (data)这里监听的是当前自己这个用户的,因为是用自己的唯一标识作为监听函数名的。

socketIOServer.getClient(roomMap.get(roomId)).sendEvent(roomId, data) ;那个用户发来的数据就将客户的唯一标识作为监听函数推数据过去。

  • 测试

因为我前端部署了两套一模一样的,模拟两个人。

将前后端都启动起来。

四、业务设计描述

如果在线人数非常多的情况下,后天将用户登录的sessionID就是那个UUID和用户的唯一标识保存在Map集合中是不现实的,建议保存在Redis中。用户唯一标识可以作为key,回话UUID作为value。当设置用户表的时候,用户ID用分布式ID策略生成。前端登录成功后就可以获取到自己的ID,然后在前端就可以作为自己的用户唯一标识了。当登录成功时,可以将所有在线的客户存入一个Redis库中,需要使用时就直接在这个Redis库中查询。客户单连接失败了,就说明已经下线了,就在这张Redis库中删除用户信息。但是需要注意,如果同一个用户在不同机器上登录呢?用户的这个唯一标识是不是不能直接作为Rediskey,这个key需要在加工处理。

但是当其他用户想要给没有在线的用户发送信息,这时我们发现目标用户已经不在线了。可以将需要发送的这些信息保存到消息队列中,当目标用户上线我们在发送给目标用户。

五、广播式发送消息

今后可以将订阅的事件名和数据都写成动态的,用户需要开启什么监听直接传入动态的数据进来就行了。关键订阅了这个事件名保存在哪里呢?跟踪代码后发现,最终这里的订阅的事件名都是保存在集合中的,所以不合适开启的订阅事件名过多。

  • 测试

将两个客户端你都启动,但是一个都不订阅的情况下,在后端发送一个text订阅。两个客户端都没有收到任何数据,说明OK。

将客户唯一标识为 WIM2000的开启订阅,在后端发送一个订阅请求。

将两个都开启订阅,这样两个都收到text的订阅信息。

噢啦,暂时就讲解到这里。

socketio实现方式相关推荐

  1. socketio mysql_socket.io 在java与微信小程序上的应用

    最近有一个这样的功能场景.用户操作完成后.服务器主动通知另一个客户端显示结果. 这里涉及一个服务器推的这么一个东西.需要实现这么一个功能,对比了几个实现方式.最终选择了socket.io. 1.com ...

  2. socketio mysql_Golang + Socket.io

    在 Go 中使用 Socket.IO Websocket Websocket是全双工的基于TCP层的通信协议,为浏览器及网站服务器提供处理流式推送消息的方式.它不同于HTTP协议,但仍依赖HTTP的U ...

  3. Flask教程(十九)SocketIO

    软硬件环境 windows 10 64bit anaconda3 with python 3.7 pycharm 2020.1.2 flask 1.1.2 flask-socketio 4.3.1 什 ...

  4. 【Web技术】1091- 跨浏览器窗口 ,7种方式,你还知道几种呢?

    前言 为什么会扯到这个话题,最初是源于听 https://y.qq.com/ QQ音乐, 播放器处于单独的一个页面 当你在另外的一个页面搜索到你满意的歌曲的时候,点击播放或添加到播放队列 你会发现,播 ...

  5. 一文搞懂四种 WebSocket 使用方式

    在上家公司做IM消息系统的时候,一直是使用 WebSocket 作为收发消息的基础组件,今天就和大家聊聊在 Java 中,使用 WebSocket 所常见的四种姿势,如果大家以后或者现在碰到有要使用 ...

  6. 什么是socketIO?

    SocketIO是在客户端和服务端之间建立的双向通信数据交换技术,底层使用EngineIO.SocketIO的的客户端使用Engine.IO-Client,服务端使用Engine.IO实现. Sock ...

  7. 实时通信 socketio nio 总结

    公司要求多一个实时通信的功能 解决思路如下 架构图: 后台管理页面实时显示在线的终端情况 终端服务器和后台服务器之间用NIO通信 当有终端登录登出,后台管理服务器(服务端)接收终端服务器(客户端) 接 ...

  8. Creator+微信小游戏(2):服务器远程加载资源(4M限制、socketio问题)

    文章目录 1.资源放哪里? 2.Creator发布的问题 3.微信开发工具的问题 4.socket.io问题! 5.手机预览黑屏 以下讲解以 cocos creator为例.笔者版本2.0.6. 1. ...

  9. SocketIO介绍及用法

    转载自:https://zhuanlan.zhihu.com/p/422664879 SocketIO是在客户端和服务端之间建立的双向通信数据交换技术,底层使用EngineIO.SocketIO的的客 ...

最新文章

  1. C++对象模型8——构造函数和析构函数中对虚函数的调用、全局对象构造和析构、局部static数组的内存分配
  2. Python编程语言学习:包导入和模块搜索路径简介、使用方法之详细攻略
  3. LiveVideoStackCon 2018推出学生优惠票
  4. 如何给远程计算机添加用户,如何访问远程计算机以添加/删除/管理用户帐户?...
  5. 【HTML基础】表格和表单
  6. node 更新_被创造者嫌弃,Node.js 如何应对来自 Deno 的挑战
  7. XenApp6.5启用3D功能
  8. java 种子填充算法_种子填充算法
  9. 从零开始搭建EasyDarwin环境——git的安装下载及拉取EasyDarwin代码运行
  10. LabVIEW编程LabVIEW开发 常用运动控制器比较
  11. 5分钟通过水痘事件来认识系统架构
  12. Python基础数据类型---列表、元组、字典、集合、编码进价、数据类型转换
  13. 什么是5G消息?有什么应用价值?如何开通服务?
  14. Lenovo 拯救者15ISK升级BIOS
  15. CToolBar的使用总结(1)
  16. 破解AI开课难题!2021 全国人工智能师资培训落地厦门大学
  17. CodeMirror 基础配置指南
  18. MarkDown使用代码
  19. Android模仿360动态悬浮窗,像360悬浮窗那样,用WindowManager实现炫酷的悬浮迷你音乐盒(下)...
  20. 有一个好的人工智能导航网,学习和兴趣加倍心流状态!

热门文章

  1. html整体垂直居中,让html img图片垂直居中的三种方法
  2. 关于wince4.2 2k 页面 nand flash 驱动的问题
  3. 创建koa2项目步骤
  4. 【koa2】使用token
  5. 大学计算机基础试题第一章,大学计算机基础试题第一章
  6. Eclipse新建Maven中创建src文件夹报The folder is already a source folder错误解决办法
  7. 微信小程序使用canvas制作拼图动画
  8. 电脑系统重装步骤教程,一键重装win7系统方法
  9. 伯乐在线 android,伯乐在线博客
  10. 青龙,XDD-plus,若兰,安装