JAVA结合WebSocket实现简单客服聊天功能

您所在的位置:网站首页 java结合 JAVA结合WebSocket实现简单客服聊天功能

JAVA结合WebSocket实现简单客服聊天功能

#JAVA结合WebSocket实现简单客服聊天功能| 来源: 网络整理| 查看: 265

 

说明:该示例只简单的实现了客服聊天功能。

          1、聊天记录没有保存到数据库中,一旦服务重启,消息记录将会没有,如果需要保存到数据库中,可以扩展

          2、页面样式用的网上模板,样式可以自己进行修改

          3、只能由用户主要发起会话,管理员无法主动进行对话

          4、页面之间跳转代码没有包含在里面,请自己书写,在管理员消息列表页中,需要把该咨询的用户ID带到客服回复页面中

          5、${websocket_url} 这个为项目的URL地址

 

效果截图:

客服回复页面

(member_admin_chat.html)

管理员消息列表页

(member_admin_chat_list.html)

  用户咨询页面

(member_chat.html)

 

 

 

 

 

 

代码:

页面所需要用到的基础样式、图片,下载链接:https://www.lanzous.com/ias1kcb (这个只是自己网上下载的样式demo,可以根据自己的来)

 

pom.xml

           javax javaee-api 8.0 provided

 

或者jar包

javax.websocket-api-1.0.jar

下载地址:https://yvioo.lanzous.com/i3AXkhl3s3c

 

 

 

配置类

WebSocketConfig.java

package com.config; import javax.websocket.Endpoint; import javax.websocket.server.ServerApplicationConfig; import javax.websocket.server.ServerEndpointConfig; import java.util.Set; public class WebSocketConfig implements ServerApplicationConfig { @Override public Set getEndpointConfigs(Set> scanned) { //在这里会把含有@ServerEndpoint注解的类扫描加载进来 ,可以在这里做过滤等操作 return scanned; } }

  

 

 消息DTO类(使用了lombok,这里不在多做说明)

ChatDTO.java

package com.websocket.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; /** * @author 。 */ @Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor public class ChatDTO { /** * 用户ID */ private String userId; /** * 用户发送信息 */ private String message; /** * 发送日期 * 消息时间格式(yyyy-MM-dd) */ private String createDate; /** * 发送时间 * 消息时间格式(yyyy-MM-dd HH:mm:ss) */ private String createTime; }

  

 

用户DTO类

ChatUserDTO.java

package com.websocket.dto; import com.entity.CmsUser; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; /** * @author 。 */ @Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor public class ChatUserDTO { /** * 用户id */ private String userId; /** * 用户名 */ private String userName; /** * 用户图片 */ private String userImg; public ChatUserDTO convertUser(CmsUser user){ ChatUserDTO chatUserDTO=new ChatUserDTO(); chatUserDTO.setUserId(user.getId()+"") .setUserName(user.getUsername()) .setUserImg(user.getUserImg()); return chatUserDTO; } }

  

 

 

ChatWebSocket.java

package com.websocket; import com.service.RedisService; import com.util.DateFormatUtils; import com.entity.CmsUser; import com.manager.CmsUserMng; import com.enums.ChatTypeEnum; import com.websocket.Constants; import com.websocket.dto.ChatDTO; import com.websocket.dto.ChatUserDTO; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.commons.lang.StringUtils; import org.springframework.web.context.ContextLoader; import org.springframework.web.context.WebApplicationContext; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.*; /** * @author 。 */ @ServerEndpoint(value = "/chat_websocket") public class ChatWebSocket { private RedisService redisService; private CmsUserMng cmsUserMng; public ChatWebSocket() { WebApplicationContext webctx = ContextLoader.getCurrentWebApplicationContext(); this.redisService = (RedisService) webctx.getBean("redisService"); this.cmsUserMng = (CmsUserMng) webctx.getBean("cmsUserMng"); } /** * 存储用户id */ public static Map userMap = new HashMap(); /** * 聊天记录 */ public static Map chatRecordMap = new HashMap(); /** * 管理员列表session */ public static Session adminSession; /** * 创建 * * @param session */ @OnOpen public void onOpen(Session session) { Map requestParameterMap = session.getRequestParameterMap(); List strs = requestParameterMap.get("msg"); if (strs != null && strs.size() > 0) { String json = strs.get(0); //从聊天集中去掉该集合 JSONObject object = JSONObject.fromObject(json); String userId = object.getString("user_id"); String chatType = object.getString("chat_type"); /*--------------管理员列表-----------------------*/ if (ChatTypeEnum.adminListChatType.getKey().equalsIgnoreCase(chatType)) { adminSession = session; List list = getUserList(userMap); //遍历所有聊天用户集合的id chat_list_show(adminSession, list); return; } /*--------------管理员聊天框打开-----------------------*/ if (ChatTypeEnum.adminChatType.getKey().equalsIgnoreCase(chatType)) { //从集合中获取用户对应的数据加入信息列表中 List sessions = (List) userMap.get(userId); if (sessions == null) { sessions = new ArrayList(); } sessions.add(session); userMap.put(userId, sessions); } /*--------------用户聊天框打开-----------------------*/ if (ChatTypeEnum.userChatType.getKey().equalsIgnoreCase(chatType)) { //判断是否建立聊天通道 List sessions = (List) userMap.get(userId); if (sessions == null) { sessions = new ArrayList(); } sessions.add(session); userMap.put(userId, sessions); } //聊天记录信息存放 List chatRecords = (List) chatRecordMap.get(userId); if (chatRecords != null) { chat((List) userMap.get(userId), chatRecords); } } } /** * 发送消息 * * @param json {userId:'',message:'',create_time:'',create_date:'',chat_type:'admin_list/admin_chat/user_chat'} * admin_list:表示客服列表数据请求 * admin_chat:表示客服回复页面请求 * user_chat表示用户消息页面请求 * * * @throws Exception */ @OnMessage public void onMessage(Session session, String json) { JSONObject object = JSONObject.fromObject(json); //用户ID String userId = object.getString("user_id"); //用户发送的信息 String message = object.getString("message"); //请求类型 String chatType = object.getString("chat_type"); /*--------------管理员聊天-----------------------*/ if (ChatTypeEnum.adminChatType.getKey().equalsIgnoreCase(chatType)) { //把管理员加入用户建立的聊天管道中 //用户聊天 //封装请求参数,时间为当前时间 ChatDTO chatDTO = new ChatDTO(); //userId=0表示是客服的回复 chatDTO.setUserId("0") .setMessage(message) .setCreateDate(DateFormatUtils.formatDate(new Date())) .setCreateTime(DateFormatUtils.formatDateTime(new Date())); //聊天记录信息存放 List chatRecords = (List) chatRecordMap.get(userId); if (chatRecords == null) { chatRecords = new ArrayList(); } chatRecords.add(JSONObject.fromObject(chatDTO)); chatRecordMap.put(userId, chatRecords); chat((List) userMap.get(userId), chatRecords); } /*--------------用户聊天-----------------------*/ if (ChatTypeEnum.userChatType.getKey().equalsIgnoreCase(chatType)) { //封装请求参数,时间为当前时间 ChatDTO chatDTO = new ChatDTO(); chatDTO.setUserId(userId) .setMessage(message) .setCreateDate(DateFormatUtils.formatDate(new Date())) .setCreateTime(DateFormatUtils.formatDateTime(new Date())); String key = chatDTO.getUserId(); //聊天记录信息存放 List chatRecords = (List) chatRecordMap.get(key); if (chatRecords == null) { chatRecords = new ArrayList(); } chatRecords.add(JSONObject.fromObject(chatDTO)); chatRecordMap.put(key, chatRecords); chat((List) userMap.get(key), chatRecords); if (adminSession != null) { List list = getUserList(userMap); //遍历所有聊天用户集合的id chat_list_show(adminSession, list); } } } /** * 关闭 */ @OnClose public void onClose(Session session) { Map requestParameterMap = session.getRequestParameterMap(); List strs = requestParameterMap.get("msg"); if (strs != null && strs.size() > 0) { String json = strs.get(0); JSONObject object = JSONObject.fromObject(json); String userId = object.getString("user_id"); String chatType = object.getString("chat_type"); /*--------------管理员聊天框关闭-----------------------*/ if (ChatTypeEnum.adminChatType.getKey().equalsIgnoreCase(chatType)) { } /*--------------用户聊天框关闭-----------------------*/ if (ChatTypeEnum.userChatType.getKey().equalsIgnoreCase(chatType)) { } } } /** * 发生错误 * * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { System.out.println("发生错误"); error.printStackTrace(); } /** * 消息广播 * * @param sessions * @param messages */ public void chat(List sessions, List messages) { for (Iterator it = sessions.iterator(); it.hasNext(); ) { Session session = (Session) it.next(); try { if (session.isOpen()) { //当当前会话没有被关闭 发送消息 session.getBasicRemote().sendText(JSONArray.fromObject(messages) + ""); } } catch (IOException e) { e.printStackTrace(); } } } /** * 聊天列表显示 */ public void chat_list_show(Session session, List list) { try { if (session.isOpen()) { //当当前会话没有被关闭 发送消息 session.getBasicRemote().sendText(JSONArray.fromObject(list) + ""); } } catch (IOException e) { e.printStackTrace(); } } /** * 通过id获取用户数据 * * @return */ public List getUserList(Map userMap) { List list = new ArrayList(); for (Object str : userMap.keySet()) { ChatUserDTO chatUserDTO = new ChatUserDTO(); CmsUser user = cmsUserMng.findById(Integer.valueOf(str + "")); list.add(chatUserDTO.convertUser(user)); } return list; } }

 

 聊天枚举类

ChatTypeEnum.java

 

package com.websocket; /** * @author 。 */ public enum ChatTypeEnum { adminListChatType("admin_list", "管理员列表"), adminChatType("admin_chat", "管理员聊天"), userChatType("user_chat", "用户聊天"), chatCountType("chat_count","消息数目"); private String key; public String value; ChatTypeEnum() { } ChatTypeEnum(String key, String value) { this.key = key; this.value = value; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }

 

 

 用户咨询页面

member_chat.html

1 doctype html> 2 3 4 5 6 8 客服咨询 9 10 11 12 13 14 15 16 17 18 客服 19 20 21 22 23 24 25 26 发送 27 28 29 30 //聊天 31 var ws; 32 var obj = { 33 user_id: '${user.id}', 34 message: '', 35 chat_type: "user_chat" 36 } 37 var target = "ws:${websocket_url!}/chat_websocket?msg=" + encodeURI(JSON.stringify(obj)); 38 39 40 var canSend = false; 41 $(function () { 42 43 //处理浏览器兼容性 44 if ('WebSocket' in window) { 45 ws = new WebSocket(target); 46 } else if ('MozWebSocket' in window) { 47 ws = new MozWebSocket(target); 48 } else { 49 alert('WebSocket is not supported by this browser.'); 50 return; 51 } 52 53 ws.onopen = function () { 54 55 }; 56 ws.onmessage = function (event) { 57 var data = JSON.parse(event.data); 58 console.log(data) 59 $('#message').html(""); 60 for (var i = 0; i 0) { 76 $(this).next().css('background', '#114F8E').prop('disabled', true); 77 canSend = true; 78 } else { 79 $(this).next().css('background', '#ddd').prop('disabled', false); 80 canSend = false; 81 } 82 }) 83 $('#footer .send').click(send) 84 $("#footer .my-input").keydown(function (e) { 85 if (e.keyCode == 13) { 86 return send(); 87 } 88 }); 89 }) 90 91 /* 对方消息div */ 92 function reply(headSrc, str) { 93 var html = "客服

" + str + "

"; 94 return upView(html); 95 } 96 97 /* 自己消息div */ 98 function ask(headSrc, str) { 99 var html = "" + "

" + str + "

"; 100 return upView(html); 101 } 102 103 function upView(html) { 104 var message = $('#message'); 105 message.append(html); 106 var h = message.outerHeight() - window.innerHeight; 107 window.scrollTo(0, document.body.scrollHeight) 108 return; 109 } 110 111 function send() { 112 if (canSend) { 113 var input = $("#footer .my-input"); 114 var val = input.val() 115 var obj = { 116 user_id: '${user.id}', 117 message: val, 118 chat_type: "user_chat" 119 } 120 ws.send(JSON.stringify(obj)); 121 //ask("/${res}/chat/images/touxiangm.png", val); 122 input.val(''); 123 } 124 } 125 126 127

 

 

 

管理员消息列表页

member_admin_chat_list.html

DOCTYPE html> 聊天列表 - ${site.name} .list-group-item span{ margin-right: 10px; } [#include "../file/file_nav.html" /] 14 Cras justo odio var ws; var obj={ user_id:'', message:'', chat_type:"admin_list" } var target="ws:${websocket_url}/chat_websocket?msg="+encodeURI(JSON.stringify(obj)); $(function () { //处理浏览器兼容性 if ('WebSocket' in window) { ws = new WebSocket(target); } else if ('MozWebSocket' in window) { ws = new MozWebSocket(target); } else { alert('WebSocket is not supported by this browser.'); return; } ws.onmessage = function (event) { var data=JSON.parse(event.data); var html=""; if (data!=null&&data.length>0){ for (var i=0;idoctype html> 客服咨询 客服 发送 //聊天 var ws; var obj = { user_id: '${user.id}', message: '', chat_type: "user_chat" } var target = "ws:${websocket_url!}/chat_websocket?msg=" + encodeURI(JSON.stringify(obj)); var canSend = false; $(function () { //处理浏览器兼容性 if ('WebSocket' in window) { ws = new WebSocket(target); } else if ('MozWebSocket' in window) { ws = new MozWebSocket(target); } else { alert('WebSocket is not supported by this browser.'); return; } ws.onopen = function () { }; ws.onmessage = function (event) { var data = JSON.parse(event.data); console.log(data) $('#message').html(""); for (var i = 0; i 0) { $(this).next().css('background', '#114F8E').prop('disabled', true); canSend = true; } else { $(this).next().css('background', '#ddd').prop('disabled', false); canSend = false; } }) $('#footer .send').click(send) $("#footer .my-input").keydown(function (e) { if (e.keyCode == 13) { return send(); } }); }) /* 对方消息div */ function reply(headSrc, str) { var html = "客服

" + str + "

"; return upView(html); } /* 自己消息div */ function ask(headSrc, str) { var html = "" + "

" + str + "

"; return upView(html); } function upView(html) { var message = $('#message'); message.append(html); var h = message.outerHeight() - window.innerHeight; window.scrollTo(0, document.body.scrollHeight) return; } function send() { if (canSend) { var input = $("#footer .my-input"); var val = input.val() var obj = {user_id: '${user.id}', message: val, chat_type: "user_chat"} ws.send(JSON.stringify(obj)); //ask("/${res}/chat/images/touxiangm.png", val); input.val(''); } }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3