目录

  • 1 获取HttpSession值
  • 2 @PathParam获取用户对象
  • 3 区分不同客户端

1 获取HttpSession值

在使用websocket来制作多人即时聊天工具的时候,难免会遇到一个问题,如何区分不同的客户端。想要解决这个问题就等于是要解决这样一个问题:如何把当前登录用户的userId传给服务端呢?因为不同的客户端代表着不同的用户,做到了获取不同客户端的userId那么自然就把不同的客户端区分开来了。两种可行获取客户端userId的方法一种是通过在Server取HttpSession中的值获取当前用户,一种是直接在客户端建立连接时附带上用户的值。

当我们在完成用户登录的功能时,用户登录成功,则将当前用户放入HttpSession中,这是一种很常见的做法,这一部分代码如下(框架是SpringMVC,不详细介绍,具体代码请以自己所用框架为准):

if(Objects.equals(userDetail.getUserDetailPassword(), userPassword)){//如果当前用户登录成功,则将user对象放入httpSession的currentUserhttpSession.setAttribute("currentUser",user);resoult = "success";}

那么接下来问题的关键就来了,我们怎么在Server中获取在这里放入HttpSession中的User对象呢,直接获取肯定是不行的,不卖关子,直接放代码。
注意,结构如图:

新建一个GetHttpSessionConfigurator类,内容如下:

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;public class GetHttpSessionConfigurator extends Configurator{@Overridepublic void modifyHandshake(ServerEndpointConfig sec,HandshakeRequest request, HandshakeResponse response) {HttpSession httpSession=(HttpSession) request.getHttpSession();sec.getUserProperties().put(HttpSession.class.getName(),httpSession);}
}

然后在Server里面注解的地方加上一句:

@ServerEndpoint(value="/server/",configurator=GetHttpSessionConfigurator.class)

此时,我们就已经可以用

@OnOpenpublic void onOpen(Session session, EndpointConfig config){HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());}

来获取httpSession对象了,然后直接取出currentUser存储的用户对象就可以了。

但是,在这里我产生了一个问题:原则上来讲我在server获取的httpsession中取出来的用户对象就是现在正和服务端建立连接的对象,因为这种情况的操作肯定是先登录,然后直接建立连接,可是在实际中多用户同时登录时就不一定是这样子了。因为登录是客户端发起的操作,建立连接也是客户端发起的操作,且不说在客户端这两个操作是否是紧密相连,就算是紧密相连,从服务器验证成功(此时已经放入currentUser对象)返回登录结果给客户端到客户端向服务端发起连接这中间因为网络原因也是会消耗一定时间的。那么这时候一件尴尬的事情就发生了:此时,另一个用户也在登录,并且在之前用户两个操作期间完成了登录验证操作,那么第一个用户连接建立之后取出的use对象就不是这个用户的而是第二个用户的,这就乱套了。这种方法相当于是 ,用户A先对服务器说,记住了,我叫A,然后过了一会儿来说,我要建立连接,我是刚刚告诉你名字那个人。那如果B在A离开那会儿也告诉了服务器我叫B,那么服务器就会把A当成B了。
当前,上面我所说的我没办法去验证,如果我对HttpSession理解错误那就另当别论了。(应该没理解错吧)如果理解有误还请大神指正。
所以,感觉上来讲还是第二种方法靠谱一点。

2 @PathParam获取用户对象

这种方法是在建立连接时把userId放在建立连接的申请之中,这样的话就不会乱掉了:因为用户A登录成功之后我就把用户A的user对象传回去了,然后用户A拿着自己的userId来对客户端说我要建立连接我是A,服务端自然不会搞错。实现方法如下:
服务端注解地方如下:

@ServerEndpoint(value="/server/{userId}")

方法参数如下:

@OnOpenpublic void onOpen(@PathParam("userId")String userId,Session session)

服务端在建立连接请求时路径如下(cp是jsp中的:)

<c:set var="cp" value="${pageContext.request.contextPath}" />

currentUser就是我们之前登录成功时放入httpSession的值,这个值即便别的用户登录也不会被刷新因为它是被保存在自己的浏览器之中的。

ws = "ws://localhost:8080" + "${cp}" + "/server"+"/${currentUser.userId}";

这样的话,服务端就获取到了当前建立连接的用户了。

3 区分不同客户端

能够获取不同用户userId之后,我们就可以在服务端进行如下操作来区分用户了,具体见注释。(为了突出要点,代码做了精简,仅仅用于示范区分不同的用户)

    public class Server {//存放每个客户端对应的Server对象,可以考虑使用Map来代替,key作为用户标识private static CopyOnWriteArraySet<Server> server = new CopyOnWriteArraySet<Server>();//表示与某个用户的连接会话,通过它给客户端发送数据@SuppressWarnings("unused")private Session session;//用户idprivate String userId;//用户id和websocket的session绑定的路由表@SuppressWarnings("rawtypes")private static Map routeTable = new HashMap<>();/*** 连接建立成功调用的方法* @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据*/@SuppressWarnings("unchecked")@OnOpenpublic void onOpen(@PathParam("userId")String userIds,Session session){this.session = session;//获取当前登录用户的idthis.userId=userIds;//将用户id和session绑定到路由表//绑定之后就可以在其它地方根据id来获取session,这时两个用户私聊就可以实现了routeTable.put(userId, session);}//其它部分代码就不放了

WebSocket区分不同客户端方法相关推荐

  1. WebSocket区分不同客户端两种方法(HttpSession和@PathParam)

    介绍 在使用websocket来制作多人即时聊天工具的时候,难免会遇到一个问题,如何区分不同的客户端.想要解决这个问题就等于是要解决这样一个问题:如何把当前登录用户的userId传给服务端呢?因为不同 ...

  2. websocket如何区分用户_WebSocket区分不同客户端两种方法(HttpSession和@PathParam)

    介绍 在使用websocket来制作多人即时聊天工具的时候,难免会遇到一个问题,如何区分不同的客户端.想要解决这个问题就等于是要解决这样一个问题:如何把当前登录用户的userId传给服务端呢?因为不同 ...

  3. websocket 更新点位 浏览器卡顿_我们来看看Swoole是如何实现WebSocket服务器及客户端的...

    php自学中心 2019-11-08 10:25:30 文章来自:laravel学院WebSocket 概述 在此之前,有必要对 WebSocket 的原理做简单的说明,WebSocket 复用了 H ...

  4. hbuilderx内置服务器启动失败_我们来看看Swoole是如何实现WebSocket服务器及客户端的...

    文章来自:laravel学院 WebSocket 概述 在此之前,有必要对 WebSocket 的原理做简单的说明,WebSocket 复用了 HTTP 协议来实现握手,然后通过请求报文中的 Upgr ...

  5. socket服务器区分各个客户端信息,socket服务器如何区分哪个客户端

    socket服务器如何区分哪个客户端 内容精选 换一换 要访问您的文件系统,如果是Linux云服务器,您需要在Linux云服务器上安装NFS客户端后使用挂载命令挂载文件系统:如果是Windows云服务 ...

  6. qt通过websocket和html通信,QT Websocket实现服务器客户端通讯(服务端部分)

    接上文QT Websocket实现服务器客户端通讯(客户端部分)web https://blog.csdn.net/qq_39573345/article/details/80682232 服务器 S ...

  7. jetson nano 安装向日葵客户端方法

    jetson nano 安装向日葵客户端方法 Jetson nano/nx使用麒麟arm版向日葵实现远程控制 第一步 切换桌面管理为 lightdm sudo apt-get update sudo ...

  8. javascript python 通信_Python通过websocket与js客户端通信示例分析

    具体的 websocket 介绍可见 http://zh.wikipedia.org/wiki/WebSocket 这里,介绍如何使用 Python 与前端 js 进行通信. websocket 使用 ...

  9. java h5获取ip,websocket中获取客户端通信的真实IP

    一些场景中,我们要对websocket客户端的ip进行校验,如果是黑名单,或者不被允许的则不应该让他访问业务系统. 笔者本地使用了两个Websocket技术原型,一个基于Netty封装的Websock ...

最新文章

  1. 减肥难?别急,精准调控细菌的方法已横空出世!
  2. win mysql 最大连接_常用的三种修改mysql最大连接数的方法
  3. C++ STL之vector常用方法
  4. 转载:【OpenCV入门教程之四】 ROI区域图像叠加初级图像混合 全剖析
  5. Navisworks Api Tool
  6. 你们要的印度布线,这是一种极端的牛X
  7. Hadoop赠品–综述
  8. Windows编程初步(二)
  9. Android studio第四次作业
  10. While 1比While True快?
  11. android 打开微信代码,微信跳转浏览器或提示手机端打开HTML代码
  12. echarts地图map下钻到镇街、KMZ文件转GeoJson、合成自定义区域
  13. 盘点(腾讯字节谷歌等大厂)面试中常见的智力题
  14. consul connect envoy 启动acls和tls后,grpc连接异常
  15. Unity3D for iOS初级教程:Part 3/3
  16. C语言图形库——EasyX基本贴图
  17. Intelligent IME
  18. 小飞鱼-致远OA 搭建借还款应用之选择借款 增加列显示
  19. 随着裁员浪潮滚滚而来,科技工作者的泡沫是否即将破灭?
  20. MxN螺旋矩阵(由外向内)

热门文章

  1. vue中的project和inject
  2. Java开发环境与搭建
  3. I'm up to my ears
  4. Android源码分析:AudioEffect
  5. iPhone手机配置fiddler代理
  6. 服务器访问时502 Server dropped connection 错误解决方法
  7. 代码解读:Fast AutoAugment
  8. C Primer Plus基础教程(1)— 初步认识C语言
  9. Android视频转换GIF图片Bitmap转GIF
  10. python 解析yaml文件