WebSocket设置在线离线以及优先展示最近聊天的人
1.设置在线状态
主要逻辑:
1.用户连接之后,首先后端执行onOpen,传入用户的id,然后写入到redis中
RedisConfig.java 中加入
@Bean public RedisTemplate < String , String > redisTemplate ( ) { RedisTemplate < String , String > redisTemplate = new StringRedisTemplate ( ) ; return redisTemplate; } @Bean public ValueOperations < String , String > stringValueOperations ( RedisTemplate < String , String > redisTemplate) { return redisTemplate. opsForValue ( ) ; }
@OnOpen public void onOpen ( Session session, @PathParam ( "id" ) String id) { sessionMap. put ( session. getId ( ) , session) ; userMap. put ( session. getId ( ) , id) ;
long timestamp = System . currentTimeMillis ( ) ; stringRedisTemplate. opsForValue ( ) . set ( id, "存在" + timestamp) ; log. info ( "[onOpen] 新建连接,session={}, 当前在线人数为:{}" , session. getId ( ) , userMap. size ( ) ) ; this . sendAllMessage ( JSONUtil . toJsonStr ( Dict . create ( ) . set ( "users" , userMap. values ( ) ) ) ) ; } @OnClose public void onClose ( Session session) { stringRedisTemplate. delete ( userMap. get ( session. getId ( ) ) ) ; userMap. remove ( session. getId ( ) ) ; sessionMap. remove ( session. getId ( ) ) ; log. info ( "[onClose] 有一连接关闭,session={}, 当前在线人数为:{}" , session. getId ( ) , userMap. size ( ) ) ; }
2.前端监听变化
client. onmessage = ( msg) = > { if ( msg. data) { let json = JSON. parse ( msg. data) if ( json. users && json. users. length) { this . loadOnline ( json) ; return } if ( json. content && ( json. fromuser == = this . fromUser && json. touser == = this . toUser) || json. touser == = this . fromUser && json. fromuser == = this . toUser) { this . messages. push ( json) this . scrollToBottom ( ) } if ( this . toUser == = json. fromuser) { this . setUnReadNums ( ) } else { this . loadUnReadNums ( ) } } }
3.查询在线人数
loadOnline ( json) { request. get ( '/user/selectAllOnline' ) . then ( res = > { res. data = res. data. filter ( v = > ( v. id + '_' + v. name) != = this . fromUser) this . $set ( this . users, 'USER' , res. data) } ) } ,
4.后端进行业务逻辑判断
public List < User > selectAllOnline ( User userNo) { List < User > userList = userMapper. selectAll ( userNo) ; for ( User user: userList) { String key = Integer . toString ( user. getId ( ) ) ; String value = stringRedisTemplate. opsForValue ( ) . get ( key) ; if ( value != null ) { String username = user. getUsername ( ) + "在线" ; user. setUsername ( username) ; } } return userList; }
5.注意在WebSocket直接写Redis相关操作会报错
解决方案看该帖子:https://blog.csdn.net/weixin_45730605/article/details/135898294?spm=1001.2014.3001.5502