当前位置:   article > 正文

LayIm结合原生WebSocket实现即时通讯

layim
后端代码
@Component
@CrossOrigin
public class MyHandler extends TextWebSocketHandler {
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private UserService userService;
    public static final Map<Integer, WebSocketSession> userSocketSession = new HashMap<Integer,WebSocketSession>();
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //获取传来的登录用户的id
        String idstr = session.getUri().toString().split("=")[1];
        int id = Integer.parseInt(idstr);
        System.err.println(id);
        System.err.println("用户连接成功");
        //保存对应的WebSocketSession
        userSocketSession.put(id, session);
        System.err.println("当前在线用户"+userSocketSession.size()+"人");
        List<Message> messageList = messageMapper.getOffLineMessages(id);
        if (messageList!=null){
            for (Message message : messageList) {
                try {
                    ObjectMapper objectMapper = new ObjectMapper();
                    String jsonmsg =  objectMapper.writeValueAsString(message);
                    TextMessage textMessage = new TextMessage(jsonmsg);
                    messageMapper.updateIsRead(message.getId());
                    handleTextMessage(session, textMessage);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // 消息处理方法
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message)  {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Message messageInfo = objectMapper.readValue(message.getPayload(), Message.class);
            //session.sendMessage(message);//发送给当前人
            if(messageInfo.getType().equals(MessageType.friend.name())) {
                sendMessageToUser(message,messageInfo );
            }else if(messageInfo.getType().equals(MessageType.group.name())) {
                sendMessagesToGroup(message,messageInfo);//给所有的用户发送消息
            }
        }catch (Exception e){
            System.err.println("解析失败:" + message.getPayload());
            e.printStackTrace();
        }
    }
    /**
     * 给群组发送消息
     */
    public void sendMessagesToGroup(TextMessage message,Message messageInfo) {
        List<User> users = userService.selectGroupUser(messageInfo.getToId(),messageInfo.getFoId());
        if (users != null){
            WebSocketSession session =null;
            try {
                for(User member : users){
                    System.out.println(member);
                    if (!(messageInfo.getFoId()==member.getId())){
                        System.out.println(member);
                        session = userSocketSession.get(member.getId());
                    }
                    if(session!=null && session.isOpen()){
                        try {
                            if (messageInfo.getIsRead()==false){
                                session.sendMessage(message);
                            }else {
                                session.sendMessage(message);
                                messageMapper.insert(messageInfo);
                            }
                        }catch (IOException e){
                            e.printStackTrace();
                        }
                    }else {
                        messageInfo.setIsRead(false);
                        messageMapper.insert(messageInfo);
                    }
                }

                /*if(session.isOpen()&&!messageInfo.getId().equals(clientId)){
                    session.sendMessage(message);
                }*/
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        /*Set<Integer> clientIds  = userSocketSession.keySet();
        WebSocketSession session = null;
        for (Integer clientId : clientIds) {
            session = userSocketSession.get(clientId);
            System.out.println(clientId);*/

        }

    /**
     * 给用户发送私聊消息
     */
    public void sendMessageToUser(TextMessage message,Message messageInfo) throws IOException {
        WebSocketSession session = userSocketSession.get(messageInfo.getToId());
        if (session!=null&&session.isOpen()){
            try {
                if (messageInfo.getIsRead()==false){
                    session.sendMessage(message);
                }else {
                    session.sendMessage(message);
                    messageMapper.insert(messageInfo);
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }else {
            messageInfo.setIsRead(false);
            messageMapper.insert(messageInfo);
        }
    }
    //用户退出后的处理,退出之后,要将用户信息从websocket的session中remove掉,这样用户就处于离线状态了,也不会占用系统资源
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus)  {
        try {
            if(session.isOpen()){
                session.close();
            }
            System.out.println(session.getId());
            userSocketSession.remove(session.getId());
            System.out.println(userSocketSession.size());

        }catch (Exception e){
            System.out.println("用户非正常关闭");
        }
    }
    //判断用户是否在线
    public boolean isUserOnline(Integer id){
        return userSocketSession.containsKey(id);
    }
}

前端代码 

        写前端代码前首先要导入layim的相关文件

//JS
layui.config({
   base: ''
   ,layimPath: '/src/' //配置 layim.js 所在目录
   ,layimAssetsPath: '/src/layim-assets/' //layim 资源文件所在目录
}).extend({
   layim: layui.cache.layimPath + 'layim' //配置 layim 组件所在的路径
}).use(['layim','form'], function() {
   var layim = layui.layim;
   var form = layui.form;

   var socket = null;
   //连接websocket的ip地址
   var ip = "localhost:80";//比如localhost
   var myid = $('#myid').val();
   //动态修改查
   var im = {
      init: function () {
         if ('WebSocket' in window) {
            //var socketUrl = 'ws://:80/myHandler?myid=' +${currentUserId};
            var socketUrl = 'ws://'+ip+'/myHandler?myid='+myid;
            socket = new WebSocket(socketUrl);
            im.startListener();
         } else {
            alert('当前浏览器不支持WebSocket功能,请更换浏览器访问。');
         }
      },
      startListener: function () {
         if (socket) {
            // 连接发生错误的回调方法
            socket.onerror = function () {
               console.log("通讯连接失败!");
            };
            // 连接成功建立的回调方法
            socket.onopen = function (event) {
               layim.config({
                  option:{
                     chatLogTool: [
                        {
                           alias: 'image',
                           title: '图片',
                           icon: '&#xe603;',
                           event: function(name, path, type){
                              // 发送图片消息的代码

                           }
                        },
                        {
                           alias: 'face',
                           title: '表情',
                           icon: '&#xe60d;',
                           // 注释掉以下两行代码,即可隐藏表情包面板
                           /*content:     '<ul class="layui-layim-face-main"></ul>',
                           facePath:    '/src/layim-assets/images/face'*/
                        }
                     ]
                  },
                  init:{
                     url:'/init',
                     data:{
                        id:myid
                     }
                  }
                  ,uploadImage:{
                     url:'/upload/image',
                     type:'post',
                  },
                  isfriend:true,
                  isgroup:true,
                  min: false,
                  members: {
                     url: '/userMembers'
                     ,data: {
                        groupId:1
                     }
                  },
                  /*brief: true //是否简约模式(如果true则不显示主面板)*/
                  group:{
                     url:'userGroup',
                     name:'我的群聊'
                     ,icon: 'layui-icon-group'
                  }
               });
               console.log("通讯连接成功");
            }
            // 接收到消息的回调方法
            socket.onmessage = function (event) {
               console.log("通讯接收到消息");
               var message = JSON.parse(event.data);
               if (message.type === 'friend') {
                  // 私聊消息
                  var friendId = message.foId === myid ? message.toId : message.foId;
                  // 将消息添加到对话框中
                  layim.getMessage({
                     username: message.username,
                     avatar: message.avatar,
                     id: friendId,
                     type: 'friend',
                     content: message.content,
                     timestamp: message.time
                  });
               } else if (message.type === 'group') {
                  // 群聊消息
                  var groupId = message.toId;
                  // 将消息添加到对话框中
                  layim.getMessage({
                     username: message.username,
                     avatar: message.avatar,
                     id: groupId,
                     type: 'group',
                     content: message.content,
                     timestamp: message.time,
                     foId: message.foId
                  });
               }
            }
            // 连接关闭的回调方法
            socket.onclose = function () {
               console.log("通讯关闭连接!!");
            }
            layim.on('ready', function() {
               //获取当前用户的ID
               //添加“添加好友”按钮
               $('#layui-layim').find('.layui-layim-tool').append('<li class="layui-icon layim-add-friend" title="添加好友">&#xe654;</li>');
               //为“添加好友”按钮绑定点击事件
               $('.layim-add-friend').on('click', function() {
                  layer.prompt({
                     formType: 0,
                     value: '',
                     title: '请输入好友ID',
                     shadeClose: true
                  }, function(value, index, elem) {
                     //向后台发送添加好友请求
                     $.post('/addFriend', { myId: myid, friendId: value }, function(res) {
                        if (res.code === 0) {
                           layer.msg('申请发送成功!');
                        } else {
                           layer.msg(res.msg);
                        }
                     });
                     layer.close(index);
                  });
               });
            });
            socket.addEventListener('message',function (event){
               var message = JSON.parse(event.data);
               switch (message.type) {
                  case 'receiveMessage':
                     layim.getMessage(message.data);
                     break;
                  case 'friendStatus':
                     layim.setFriendStatus(message.data);
                     break;
                  case 'addFriend':
                     //接收到好友申请,显示添加好友确认框
                     layer.open({
                        title: '添加好友',
                        content: message.data.username + '请求添加你为好友,是否同意?',
                        btn: ['同意', '拒绝'],
                        yes: function(index, layero) {
                           //向后台发送同意好友申请请求
                           $.post('/agreeAddFriend', { userID: message.data.friendId }, function(res) {
                              if (res.code === 0) {
                                 layer.msg('添加好友成功!');
                              } else {
                                 layer.msg(res.msg);
                              }
                           });
                           layer.close(index);
                        },
                        btn2: function(index, layero) {
                           //向后台发送拒绝好友申请请求
                           $.post('/refuseAddFriend', { userID: message.data.friendId }, function(res) {
                              if (res.code === 0) {
                                 layer.msg('已拒绝好友请求!');
                              } else {
                                 layer.msg(res.msg);
                              }
                           });
                           layer.close(index);
                        }
                     });
                     break;
                     //其他消息类型的处理
               }
            });
            layim.on('sendMessage', function (data) {
               var chatData = {
                  content: data.mine.content,
                  username:data.mine.username,
                  avatar:'',
                  toId: data.to.id,
                  foId:myid,
                  type: data.to.type,
                  sendTime: Date.now()
               };
               socket.send(JSON.stringify(chatData));
            });
         }
      },
   };
   im.init();

});

自己随意写项目里加的即时通讯,功能不全只实现了私聊和群聊,后续会有更新

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/404302
推荐阅读
相关标签
  

闽ICP备14008679号