当前位置:   article > 正文

商城项目-客服功能_商城系统的客服功能都怎么写的

商城系统的客服功能都怎么写的

最近一段时间我们在完善项目,我们在写的项目是一个商城项目。上次考核的时候考虑到进度问题,客服功能只做了一半,这次项目我对它进行了完善。

客服功能因为要实现即时通信,我主要是基于websocket实现的,它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的。因为是第一次去写类似的功能,所以在实现过程中遇到了很多问题。

离线消息

因为客服和用户并不是一直在线的,但是在用户离线的时候别人向他发送的消息他也应该接收到。所以在发送信息的时候我加了一个判断,当用户离线的时候将接收到的信息存到redis里面,在用户连接websocket的查询redis判断用户是否有离线的信息,如果有,在登录的时候一起发送过来。

发送消息

  1. Session userSession = map.get("user:" + userId);
  2. if (userSession != null) {
  3. userSession.getAsyncRemote().sendText(msgJson);
  4. }
  5. {
  6. String userKey = "msg@" + message.getUserId() + ":offLine";
  7. redisUtil.lLeftPush(userKey, msgJson);
  8. }

登录时判断

  1. String chatKey= "msg@" +userId + ":offLine";
  2. while(redisUtil.hasKey(chatKey)&&redisUtil.lLen(chatKey)!=0){
  3. String msg = redisUtil.lRightPop(chatKey);
  4. session.getAsyncRemote().sendText(msg);
  5. }

角色绑定:

因为店铺与客服是一对多的关系,一个店铺里面可以有多个客服在线,当用户与客服进行聊天时,要保证一个客服和一个用户进行聊天,否则不符合逻辑。所以写项目的时候我给聊天列表设置了一个状态,客服可以查看所有的聊天列表,然后选择性进行接取业务,当一个聊天列表被一个客服接取后,其他客服不能进入这个聊天列表与用户进行聊天。

因为店铺与客服的一对多的关系,所以在用户反馈的时候该店铺的所有客服都可以看到聊天记录。我在用户给店铺发送信息的时候,先查询店铺里面有哪些客服,再查询客服的session,遍历给客服发送消息。

  1. @ServerEndpoint(value = "/websocket/{userId}")
  2. @Component
  3. public class WebSocketUtil {
  4. private static CopyOnWriteArraySet<WebSocketUtil> webSocketSet = new CopyOnWriteArraySet<WebSocketUtil>();
  5. private Session session;
  6. private String key;
  7. private static Map<String,Session> map = new HashMap<>();
  8. // private static Map<Integer, List<Integer>> storeMap=new HashMap<>();
  9. private static RedisUtil redisUtil;
  10. private static ChatDao chatDao;
  11. @Autowired
  12. public void setRedisUtil(RedisUtil redisUtil){
  13. WebSocketUtil.redisUtil = redisUtil;
  14. }
  15. @Autowired
  16. public void setChatDao(ChatDao chatDao){
  17. WebSocketUtil.chatDao = chatDao;
  18. }
  19. /**
  20. * 连接建立成功调用的方法
  21. */
  22. @OnOpen
  23. public void onOpen(Session session,@PathParam("userId")Integer userId) {
  24. this.session = session;
  25. this.key="user:"+userId;
  26. map.put(key, session);
  27. String chatKey= "msg@" +userId + ":offLine";
  28. while(redisUtil.hasKey(chatKey)&&redisUtil.lLen(chatKey)!=0){
  29. String msg = redisUtil.lRightPop(chatKey);
  30. session.getAsyncRemote().sendText(msg);
  31. }
  32. webSocketSet.add(this);
  33. //加入set中
  34. System.out.println("有新连接加入:"+userId+",当前在线人数为" + webSocketSet.size());
  35. this.session.getAsyncRemote().sendText("恭喜"+userId+"成功连接上WebSocket(其频道号:"+userId+")-->当前在线人数为:"+webSocketSet.size());
  36. }
  37. /**
  38. * 连接关闭调用的方法
  39. */
  40. @OnClose
  41. public void onClose() {
  42. webSocketSet.remove(this); //从set中删除
  43. System.out.println("有一连接关闭!当前在线人数为" + webSocketSet.size());
  44. }
  45. /**
  46. * 收到客户端消息后调用的方法
  47. *
  48. * @param message 客户端发送过来的消息*/
  49. @OnMessage
  50. public void onMessage(String message,@PathParam("id") String id) {
  51. }
  52. /**
  53. * 发生错误时调用
  54. *
  55. */
  56. @OnError
  57. public void onError( Throwable error) {
  58. System.out.println("发生错误");
  59. error.printStackTrace();
  60. }
  61. /**
  62. * 群发自定义消息
  63. * */
  64. public void broadcast(String message){
  65. for (WebSocketUtil item : webSocketSet) {
  66. //同步异步说明参考:http://blog.csdn.net/who_is_xiaoming/article/details/53287691
  67. //this.session.getBasicRemote().sendText(message);
  68. item.session.getAsyncRemote().sendText(message);//异步发送消息.
  69. }
  70. }
  71. public void sendMessage(Integer userId, Integer storeId, Message message) {
  72. Session userSession = map.get("user:" + userId);
  73. String msgJson = JSON.toJSONString(message);
  74. String userListKey = "userList:" + userId + "@chat";
  75. String storeListKey = "storeList:" + storeId + "@chat";
  76. int userList = (int) Double.parseDouble(redisUtil.zScore(userListKey, storeId + "") + "");
  77. int storeList = (int) Double.parseDouble(redisUtil.zScore(storeListKey, userId + "") + "");
  78. //发送给用户.
  79. if (userSession != null) {
  80. userSession.getAsyncRemote().sendText(msgJson);
  81. }
  82. {
  83. String userKey = "msg@" + message.getUserId() + ":offLine";
  84. redisUtil.lLeftPush(userKey, msgJson);
  85. }
  86. // List<Integer> list = storeMap.get(storeId);
  87. String userKey = "msg@" + userList + ":message";
  88. redisUtil.lLeftPush(userKey, msgJson);
  89. String storeKey = "msg@" + storeList + ":message";
  90. redisUtil.lLeftPush(storeKey, msgJson);
  91. Integer chatListId;
  92. if (message.getMessageStatus() == 0) {
  93. chatListId = storeId;
  94. } else {
  95. chatListId = userId;
  96. }
  97. String numKey = "chat@No:" + chatListId + "num";
  98. if (redisUtil.hasKey(numKey)) {
  99. redisUtil.incrBy(numKey, 1);
  100. } else {
  101. redisUtil.set(numKey, "1");
  102. }
  103. List<Integer> list=null;
  104. if(redisUtil.hasKey("chatService:"+storeId)){
  105. Set<String> strings = redisUtil.setMembers("chatService:" + storeId);
  106. list = strings.stream().map(Integer::parseInt).collect(Collectors.toList());
  107. }
  108. if (list != null) {
  109. for (Integer id :
  110. list) {
  111. Session chatSession = map.get("user:" + id);
  112. String chatKey;
  113. if (chatSession != null) {
  114. chatSession.getAsyncRemote().sendText(msgJson);
  115. } else {
  116. chatKey = "msg@" + message.getUserId() + ":offLine";
  117. redisUtil.lLeftPush(chatKey, msgJson);
  118. }
  119. }
  120. }
  121. }

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

闽ICP备14008679号