在线客服系统是一套交互式沟通工具,采用PHP+MYSQL开发。高性能,不卡顿。使用它可以迅速缩小你的选择范围,联系多个供应商、客户等,也可以给你的企业一个关于用户体验的重大影响。(尾部下载完整版PHP客服系统源码)


1,首先思考群聊的实现方式。
2,再来举一反三,思考单聊的实现方式。
有一个地方需要提一下,比如要给A用户发送消息,就要根据A的userId得到连接对象,然后就会把消息发送给A用户。
1,首先是用户聊天框的js代码(html忽略)
此为用户点击在线客服按钮进入聊天框页面就执行的js代码。
说明:下面接收人id写死了为超级管理员,我这里省事情了,因为超级管理员的账号(也就是唯一标识)就是超级管理员这五个字,当真正开发时就要动态获取唯一标识了!
2,其次为后台系统客服聊天框的js代码
3,最后为服务端的websocket实例
package com.qianlong.controller;
import com.qianlong.service.SelectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
/**
* 聊天室的服务端程序
* @author Administrator
*
*/
//声明websocket某个服务端的地址
@ServerEndpoint(value = "/charRoomServer/{param}")
@Component
public class ChatRoomServer {
@Autowired
public static SelectService selectService;
private boolean firstFlag=true;
private Session session;
private String userName;
//发送人id
private String userId;
//key代表此次客户端的userId,value代表此次连接对象
private static final HashMap connectMap=new HashMap();
//保存所有用户昵称信息
//key是session的id,value是用户昵称
private static final HashMap userMap=new HashMap();
//服务端收到客户端的连接请求,连接成功后会执行此方法
@OnOpen
public void start(@PathParam(value = "param") String param, Session session) {
this.session=session;
this.userId=param; //接收参数
connectMap.put(param,this);
}
//客户端发来的信息,服务端接收
@OnMessage //接收人userId
public void chat(String clientMessage,Session session) {
//firstFlag为true是第一次进入,第二次进入之后设为false
ChatRoomServer client=null;
if(firstFlag) {
this.userName=clientMessage;
//将新进来的用户保存到用户map
userMap.put(session.getId(), userName);
try {
if("超级管理员".equals(userId)){
}else{
//构造发送给客户端的提示信息
String message=htmlMessage("大白机器人:","亲爱的"+userId+",您想了解点儿啥?");
client=(ChatRoomServer) connectMap.get(userId);
//给对应的web端发送一个文本信息
client.session.getBasicRemote().sendText(message);
}
} catch (IOException e) {
e.printStackTrace();
}
firstFlag=false;
}else {
System.err.println("clientMessage:"+userName);
//给对方发消息
String message1=htmlMessage(userId,clientMessage);
client = (ChatRoomServer) connectMap.get(userName);
if(client!=null){
try {
client.session.getBasicRemote().sendText(message1);
} catch (IOException e) {
e.printStackTrace();
}
}
//给自己窗口发消息
String message2=htmlMessage(userId,clientMessage);
client = (ChatRoomServer) connectMap.get(userId);
try {
client.session.getBasicRemote().sendText(message2);
} catch (IOException e) {
e.printStackTrace();
}
//这是将前台用户发送的消息存数据库并标记为未读,和上面通信没关系
if("超级管理员".equals(userId)){
}else{
Map map=new HashMap();
map.put("account",userId);
map.put("message",clientMessage);
map.put("addtime",new Date());
int i = selectService.chatInsert(map);
System.out.println(i);
}
}
}
/**
* 前台js的ws.close事件,会触发后台的标注onClose的方法
*/
@OnClose
public void close() {
userMap.remove(session.getId());
connectMap.remove(userId);
}
/**
* 渲染页面,把信息构造好标签再发送
*/
public String htmlMessage(String userName,String message) {
StringBuffer stringBuffer=new StringBuffer();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
stringBuffer.append("" );
stringBuffer.append(""+sf.format(new Date())+"");
stringBuffer.append("");
stringBuffer.append(""
+userName+"");
stringBuffer.append("");
stringBuffer.append("");
stringBuffer.append("");
stringBuffer.append(""+message+"");
stringBuffer.append("");
stringBuffer.append("");
//这里拼接了消息发送人的userId,在前台进行截取字符串接收发送人的userId
stringBuffer.append("|"+userName);
return stringBuffer.toString();
}
}
在websocket中进行依赖注入service并调用service方法进行数据库存储,如果按常规的方式是走不通的。
解决方式:
在该springboot项目中添加一个WebsocketConfig配置类,对service进行配置。
@Configuration
public class WebSocketConfig {
/**
* ServerEndpointExporter 用于扫描和注册所有携带 ServerEndPoint 注解的实例,
* 若部署到外部容器 则无需提供此类。
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
* 因 SpringBoot WebSocket 对每个客户端连接都会创建一个 WebSocketServer(@ServerEndpoint 注解对应的对象,Bean 注入操作会被直接略过,因而手动注入一个全局变量
*/
@Autowired
public void setSelectService(SelectService selectService) {
ChatRoomServer.selectService = selectService;
}
}
然后在websocket中注入service。


php客服系统源码包下载地址:
https://yfi.lanzouj.com/iHN4A061ok5c