1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-08-01 16:38:02 +08:00

Closed #111 支持WebIM的集群场景下使用

This commit is contained in:
Hai Liang Wang 2018-10-23 17:17:02 +08:00
parent 901e9aa621
commit 29ebd3125b
18 changed files with 1237 additions and 895 deletions

View File

@ -214,8 +214,8 @@ public class AutomaticServiceDist {
router.handler(agentUser.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), agentUser.getAppid(), outMessage); router.handler(agentUser.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), agentUser.getAppid(), outMessage);
} }
} }
// TODO #111 为坐席分配访客
NettyClients.getInstance().sendAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), agentUser); NettyClients.getInstance().publishAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), agentUser);
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -311,7 +311,8 @@ public class AutomaticServiceDist {
NettyClients.getInstance().sendCalloutEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.END.toString(), agentUser); NettyClients.getInstance().sendCalloutEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.END.toString(), agentUser);
} else { } else {
if (agentStatus != null) // WebIM 查看用户状态 if (agentStatus != null) // WebIM 查看用户状态
NettyClients.getInstance().sendAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.END.toString(), agentUser); // TODO #111 结束会话
NettyClients.getInstance().publishAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.END.toString(), agentUser);
OutMessageRouter router = null; OutMessageRouter router = null;
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel()); router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
if (router != null) { if (router != null) {
@ -500,7 +501,8 @@ public class AutomaticServiceDist {
if (agentStatus != null) { if (agentStatus != null) {
agentService = processAgentService(agentStatus, agentUser, orgi); agentService = processAgentService(agentStatus, agentUser, orgi);
publishMessage(orgi, "invite", "success", agentno); publishMessage(orgi, "invite", "success", agentno);
NettyClients.getInstance().sendAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), agentUser); // TODO #111 为坐席分配邀请的访客
NettyClients.getInstance().publishAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), agentUser);
} else { } else {
agentService = allotAgent(agentUser, orgi); agentService = allotAgent(agentUser, orgi);
} }

View File

@ -15,8 +15,10 @@
*/ */
package com.chatopera.cc.app.config; package com.chatopera.cc.app.config;
import com.chatopera.cc.util.Constants;
import com.chatopera.cc.app.schedule.CallOutWireTask; import com.chatopera.cc.app.schedule.CallOutWireTask;
import com.chatopera.cc.app.schedule.WebIMAgentDispatcher;
import com.chatopera.cc.app.schedule.WebIMOnlineUserDispatcher;
import com.chatopera.cc.util.Constants;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -38,17 +40,25 @@ public class RedisConfigure {
@Autowired @Autowired
CallOutWireTask callOutWireTask; CallOutWireTask callOutWireTask;
@Autowired
WebIMAgentDispatcher webIMAgentDispatcher;
@Autowired
WebIMOnlineUserDispatcher webIMOnlineUserDispatcher;
@Bean @Bean
RedisMessageListenerContainer redisContainer() { RedisMessageListenerContainer redisContainer() {
final RedisMessageListenerContainer container = new RedisMessageListenerContainer(); final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(jedisConnectionFactory); container.setConnectionFactory(jedisConnectionFactory);
container.addMessageListener(messageListener(), pbxEvents()); container.addMessageListener(pbxMessageListener(), pbxEvents());
container.addMessageListener(imAgentDispatchListener(), imAgentEvents());
container.addMessageListener(imOnlineUserDispatchListener(), imOnlineUserEvents());
container.setTaskExecutor(Executors.newFixedThreadPool(50)); container.setTaskExecutor(Executors.newFixedThreadPool(50));
return container; return container;
} }
@Bean @Bean
MessageListenerAdapter messageListener() { MessageListenerAdapter pbxMessageListener() {
return new MessageListenerAdapter(callOutWireTask); return new MessageListenerAdapter(callOutWireTask);
} }
@ -57,4 +67,25 @@ public class RedisConfigure {
return new PatternTopic(Constants.FS_CHANNEL_FS_TO_CC); return new PatternTopic(Constants.FS_CHANNEL_FS_TO_CC);
} }
@Bean
MessageListenerAdapter imAgentDispatchListener() {
return new MessageListenerAdapter(webIMAgentDispatcher);
}
@Bean
PatternTopic imAgentEvents() {
return new PatternTopic(Constants.INSTANT_MESSAGING_WEBIM_AGENT_CHANNEL);
}
@Bean
MessageListenerAdapter imOnlineUserDispatchListener(){
return new MessageListenerAdapter(webIMOnlineUserDispatcher);
}
@Bean
PatternTopic imOnlineUserEvents() {
return new PatternTopic(Constants.INSTANT_MESSAGING_WEBIM_ONLINE_USER_CHANNEL);
}
} }

View File

@ -768,8 +768,8 @@ public class AgentController extends Handler {
data.setUsername(super.getUser(request).getUsername()); data.setUsername(super.getUser(request).getUsername());
chatMessageRepository.save(data); chatMessageRepository.save(data);
// TODO #111 通知文件上传消息
NettyClients.getInstance().sendAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data); NettyClients.getInstance().publishAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
} }
} else { } else {
@ -1068,7 +1068,8 @@ public class AgentController extends Handler {
agentService.setAgentno(agentno); agentService.setAgentno(agentno);
agentService.setAgentusername(transAgentStatus.getUsername()); agentService.setAgentusername(transAgentStatus.getUsername());
} }
NettyClients.getInstance().sendAgentEventMessage(agentno, MainContext.MessageTypeEnum.NEW.toString(), agentUser); // TODO #111 通知转接消息
NettyClients.getInstance().publishAgentEventMessage(agentno, MainContext.MessageTypeEnum.NEW.toString(), agentUser);
} }
} else { } else {
agentUser = agentUserRepository.findByIdAndOrgi(agentuserid, super.getOrgi(request)); agentUser = agentUserRepository.findByIdAndOrgi(agentuserid, super.getOrgi(request));
@ -1317,4 +1318,4 @@ public class AgentController extends Handler {
return request(super.createRequestPageTempletResponse("redirect:/agent/index.html")); return request(super.createRequestPageTempletResponse("redirect:/agent/index.html"));
} }
} }

View File

@ -16,27 +16,17 @@
*/ */
package com.chatopera.cc.app.handler.apps.service; package com.chatopera.cc.app.handler.apps.service;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import com.chatopera.cc.app.basic.MainContext;
import com.chatopera.cc.util.IP;
import com.chatopera.cc.app.basic.MainUtils;
import com.chatopera.cc.util.Menu;
import com.chatopera.cc.app.im.client.NettyClients;
import com.chatopera.cc.app.algorithm.AutomaticServiceDist; import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
import com.chatopera.cc.app.basic.MainContext;
import com.chatopera.cc.app.basic.MainUtils;
import com.chatopera.cc.app.cache.CacheHelper; import com.chatopera.cc.app.cache.CacheHelper;
import com.chatopera.cc.util.OnlineUserUtils;
import com.chatopera.cc.app.handler.Handler; import com.chatopera.cc.app.handler.Handler;
import com.chatopera.cc.app.im.client.NettyClients;
import com.chatopera.cc.app.model.*;
import com.chatopera.cc.app.persistence.repository.*;
import com.chatopera.cc.util.IP;
import com.chatopera.cc.util.Menu;
import com.chatopera.cc.util.OnlineUserUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -48,400 +38,402 @@ import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import com.chatopera.cc.app.persistence.repository.AgentServiceRepository; import javax.persistence.criteria.CriteriaBuilder;
import com.chatopera.cc.app.persistence.repository.AgentStatusRepository; import javax.persistence.criteria.CriteriaQuery;
import com.chatopera.cc.app.persistence.repository.AgentUserRepository; import javax.persistence.criteria.Predicate;
import com.chatopera.cc.app.persistence.repository.LeaveMsgRepository; import javax.persistence.criteria.Root;
import com.chatopera.cc.app.persistence.repository.OrganRepository; import javax.servlet.http.HttpServletRequest;
import com.chatopera.cc.app.persistence.repository.OrgiSkillRelRepository; import javax.validation.Valid;
import com.chatopera.cc.app.persistence.repository.UserRepository; import java.text.ParseException;
import com.chatopera.cc.app.model.AgentService; import java.util.ArrayList;
import com.chatopera.cc.app.model.AgentStatus; import java.util.Date;
import com.chatopera.cc.app.model.AgentUser; import java.util.List;
import com.chatopera.cc.app.model.AiUser;
import com.chatopera.cc.app.model.LeaveMsg;
import com.chatopera.cc.app.model.Organ;
import com.chatopera.cc.app.model.OrgiSkillRel;
import com.chatopera.cc.app.model.User;
@Controller @Controller
@RequestMapping("/service") @RequestMapping("/service")
public class ChatServiceController extends Handler { public class ChatServiceController extends Handler {
@Autowired @Autowired
private AgentServiceRepository agentServiceRes ; private AgentServiceRepository agentServiceRes;
@Autowired @Autowired
private AgentUserRepository agentUserRes ; private AgentUserRepository agentUserRes;
@Autowired @Autowired
private AgentStatusRepository agentStatusRepository ; private AgentStatusRepository agentStatusRepository;
@Autowired @Autowired
private AgentUserRepository agentUserRepository ; private AgentUserRepository agentUserRepository;
@Autowired @Autowired
private LeaveMsgRepository leaveMsgRes ; private LeaveMsgRepository leaveMsgRes;
@Autowired @Autowired
private OrganRepository organRes ; private OrganRepository organRes;
@Autowired @Autowired
private OrganRepository organ ; private OrganRepository organ;
@Autowired @Autowired
private UserRepository user ; private UserRepository user;
@Autowired @Autowired
private UserRepository userRes ; private UserRepository userRes;
@Autowired @Autowired
private OrgiSkillRelRepository orgiSkillRelService; private OrgiSkillRelRepository orgiSkillRelService;
@RequestMapping("/history/index") @RequestMapping("/history/index")
@Menu(type = "service" , subtype = "history" , admin= true) @Menu(type = "service", subtype = "history", admin = true)
public ModelAndView index(ModelMap map , HttpServletRequest request ,final String username,final String channel ,final String servicetype,final String allocation,final String servicetimetype,final String begin,final String end) { public ModelAndView index(ModelMap map, HttpServletRequest request, final String username, final String channel, final String servicetype, final String allocation, final String servicetimetype, final String begin, final String end) {
Page<AgentService> page = agentServiceRes.findAll(new Specification<AgentService>(){ Page<AgentService> page = agentServiceRes.findAll(new Specification<AgentService>() {
@Override @Override
public Predicate toPredicate(Root<AgentService> root, CriteriaQuery<?> query,CriteriaBuilder cb) { public Predicate toPredicate(Root<AgentService> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<Predicate>(); List<Predicate> list = new ArrayList<Predicate>();
if(!StringUtils.isBlank(username)) { if (!StringUtils.isBlank(username)) {
list.add(cb.equal(root.get("username").as(String.class), username)) ; list.add(cb.equal(root.get("username").as(String.class), username));
} }
if(!StringUtils.isBlank(channel)) { if (!StringUtils.isBlank(channel)) {
list.add(cb.equal(root.get("channel").as(String.class), channel)) ; list.add(cb.equal(root.get("channel").as(String.class), channel));
} }
if(!StringUtils.isBlank(servicetype)&&!StringUtils.isBlank(allocation)) { if (!StringUtils.isBlank(servicetype) && !StringUtils.isBlank(allocation)) {
list.add(cb.equal(root.get(servicetype).as(String.class), allocation)); list.add(cb.equal(root.get(servicetype).as(String.class), allocation));
} }
if(!StringUtils.isBlank(servicetimetype)) { if (!StringUtils.isBlank(servicetimetype)) {
try { try {
if(!StringUtils.isBlank(begin) && begin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){ if (!StringUtils.isBlank(begin) && begin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")) {
list.add(cb.greaterThanOrEqualTo(root.get(servicetimetype).as(Date.class), MainUtils.dateFormate.parse(begin))) ; list.add(cb.greaterThanOrEqualTo(root.get(servicetimetype).as(Date.class), MainUtils.dateFormate.parse(begin)));
} }
if(!StringUtils.isBlank(end) && end.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){ if (!StringUtils.isBlank(end) && end.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")) {
list.add(cb.lessThanOrEqualTo(root.get(servicetimetype).as(Date.class), MainUtils.dateFormate.parse(end))) ; list.add(cb.lessThanOrEqualTo(root.get(servicetimetype).as(Date.class), MainUtils.dateFormate.parse(end)));
} }
} catch (ParseException e) { } catch (ParseException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
Predicate[] p = new Predicate[list.size()]; Predicate[] p = new Predicate[list.size()];
return cb.and(list.toArray(p)); return cb.and(list.toArray(p));
} }
},new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime")) ; }, new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime"));
map.put("agentServiceList", page) ; map.put("agentServiceList", page);
map.put("username", username) ; map.put("username", username);
map.put("channel", channel) ; map.put("channel", channel);
map.put("servicetype", servicetype) ; map.put("servicetype", servicetype);
map.put("servicetimetype", servicetimetype) ; map.put("servicetimetype", servicetimetype);
map.put("allocation", allocation); map.put("allocation", allocation);
map.put("begin", begin) ; map.put("begin", begin);
map.put("end", end) ; map.put("end", end);
map.put("deptlist",organ.findByOrgi(super.getOrgi(request))); map.put("deptlist", organ.findByOrgi(super.getOrgi(request)));
map.put("userlist",user.findByOrgiAndDatastatus(super.getOrgi(request), false)); map.put("userlist", user.findByOrgiAndDatastatus(super.getOrgi(request), false));
return request(super.createAppsTempletResponse("/apps/service/history/index")); return request(super.createAppsTempletResponse("/apps/service/history/index"));
} }
@RequestMapping("/current/index") @RequestMapping("/current/index")
@Menu(type = "service" , subtype = "current" , admin= true) @Menu(type = "service", subtype = "current", admin = true)
public ModelAndView current(ModelMap map , HttpServletRequest request) { public ModelAndView current(ModelMap map, HttpServletRequest request) {
map.put("agentServiceList", agentServiceRes.findByOrgiAndStatus(super.getOrgi(request), MainContext.AgentUserStatusEnum.INSERVICE.toString() ,new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime"))) ; map.put("agentServiceList", agentServiceRes.findByOrgiAndStatus(super.getOrgi(request), MainContext.AgentUserStatusEnum.INSERVICE.toString(), new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime")));
return request(super.createAppsTempletResponse("/apps/service/current/index")); return request(super.createAppsTempletResponse("/apps/service/current/index"));
} }
@RequestMapping("/current/trans") @RequestMapping("/current/trans")
@Menu(type = "service" , subtype = "current" , admin= true) @Menu(type = "service", subtype = "current", admin = true)
public ModelAndView trans(ModelMap map , HttpServletRequest request , @Valid String id) { public ModelAndView trans(ModelMap map, HttpServletRequest request, @Valid String id) {
if(!StringUtils.isBlank(id)){ if (!StringUtils.isBlank(id)) {
AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request)) ; AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request));
List<Organ> skillList = OnlineUserUtils.organ(super.getOrgi(request),true) ; List<Organ> skillList = OnlineUserUtils.organ(super.getOrgi(request), true);
String currentOrgan = super.getUser(request).getOrgan(); String currentOrgan = super.getUser(request).getOrgan();
if(StringUtils.isBlank(currentOrgan)) { if (StringUtils.isBlank(currentOrgan)) {
if(!skillList.isEmpty()) { if (!skillList.isEmpty()) {
currentOrgan = skillList.get(0).getId(); currentOrgan = skillList.get(0).getId();
} }
} }
List<AgentStatus> agentStatusList = AutomaticServiceDist.getAgentStatus(null , super.getOrgi(request)); List<AgentStatus> agentStatusList = AutomaticServiceDist.getAgentStatus(null, super.getOrgi(request));
List<String> usersids = new ArrayList<String>(); List<String> usersids = new ArrayList<String>();
if(!agentStatusList.isEmpty()) { if (!agentStatusList.isEmpty()) {
for(AgentStatus agentStatus:agentStatusList) { for (AgentStatus agentStatus : agentStatusList) {
if(agentStatus!=null){ if (agentStatus != null) {
usersids.add(agentStatus.getAgentno()) ; usersids.add(agentStatus.getAgentno());
} }
} }
} }
List<User> userList = userRes.findAll(usersids); List<User> userList = userRes.findAll(usersids);
for(User user : userList){ for (User user : userList) {
user.setAgentStatus((AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(user.getId(), super.getOrgi(request))); user.setAgentStatus((AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(user.getId(), super.getOrgi(request)));
} }
map.addAttribute("userList", userList) ; map.addAttribute("userList", userList);
map.addAttribute("userid", agentService.getUserid()) ; map.addAttribute("userid", agentService.getUserid());
map.addAttribute("agentserviceid", agentService.getId()) ; map.addAttribute("agentserviceid", agentService.getId());
map.addAttribute("agentuserid", agentService.getAgentuserid()) ; map.addAttribute("agentuserid", agentService.getAgentuserid());
map.addAttribute("agentservice", agentService) ; map.addAttribute("agentservice", agentService);
map.addAttribute("skillList", skillList) ; map.addAttribute("skillList", skillList);
map.addAttribute("currentorgan", currentOrgan) ; map.addAttribute("currentorgan", currentOrgan);
} }
return request(super.createRequestPageTempletResponse("/apps/service/current/transfer")); return request(super.createRequestPageTempletResponse("/apps/service/current/transfer"));
} }
@RequestMapping(value="/transfer/save") @RequestMapping(value = "/transfer/save")
@Menu(type = "apps", subtype = "transfersave") @Menu(type = "apps", subtype = "transfersave")
public ModelAndView transfersave(ModelMap map , HttpServletRequest request , @Valid String id , @Valid String agentno , @Valid String memo){ public ModelAndView transfersave(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String agentno, @Valid String memo) {
if(!StringUtils.isBlank(id)){ if (!StringUtils.isBlank(id)) {
AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request)) ; AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request));
AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(agentService.getUserid(), super.getOrgi(request)) ; AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(agentService.getUserid(), super.getOrgi(request));
if(agentUser != null){ if (agentUser != null) {
agentUser.setAgentno(agentno); agentUser.setAgentno(agentno);
CacheHelper.getAgentUserCacheBean().put(agentService.getUserid() , agentUser , super.getOrgi(request)) ; CacheHelper.getAgentUserCacheBean().put(agentService.getUserid(), agentUser, super.getOrgi(request));
agentUserRepository.save(agentUser) ; agentUserRepository.save(agentUser);
if(MainContext.AgentUserStatusEnum.INSERVICE.toString().equals(agentUser.getStatus())){ //转接 发送消息给 目标坐席 if (MainContext.AgentUserStatusEnum.INSERVICE.toString().equals(agentUser.getStatus())) { //转接 发送消息给 目标坐席
AgentStatus agentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(super.getUser(request).getId(), super.getOrgi(request)) ; AgentStatus agentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(super.getUser(request).getId(), super.getOrgi(request));
if(agentStatus!=null){ if (agentStatus != null) {
AutomaticServiceDist.updateAgentStatus(agentStatus, agentUser, super.getOrgi(request), false); AutomaticServiceDist.updateAgentStatus(agentStatus, agentUser, super.getOrgi(request), false);
} }
AgentStatus transAgentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(agentno, super.getOrgi(request)) ; AgentStatus transAgentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(agentno, super.getOrgi(request));
if(transAgentStatus!=null){ if (transAgentStatus != null) {
AutomaticServiceDist.updateAgentStatus(transAgentStatus, agentUser, super.getOrgi(request), true); AutomaticServiceDist.updateAgentStatus(transAgentStatus, agentUser, super.getOrgi(request), true);
agentService.setAgentno(agentno); agentService.setAgentno(agentno);
agentService.setAgentusername(transAgentStatus.getUsername()); agentService.setAgentusername(transAgentStatus.getUsername());
} }
NettyClients.getInstance().sendAgentEventMessage(agentno, MainContext.MessageTypeEnum.NEW.toString(), agentUser); // TODO #111 通知转接消息
} NettyClients.getInstance().publishAgentEventMessage(agentno, MainContext.MessageTypeEnum.NEW.toString(), agentUser);
}else{ }
agentUser = agentUserRepository.findByIdAndOrgi(agentService.getAgentuserid(), super.getOrgi(request)); } else {
if(agentUser!=null){ agentUser = agentUserRepository.findByIdAndOrgi(agentService.getAgentuserid(), super.getOrgi(request));
agentUser.setAgentno(agentno); if (agentUser != null) {
agentUserRepository.save(agentUser) ; agentUser.setAgentno(agentno);
} agentUserRepository.save(agentUser);
} }
}
if(agentService!=null){
agentService.setAgentno(agentno); if (agentService != null) {
if(!StringUtils.isBlank(memo)){ agentService.setAgentno(agentno);
agentService.setTransmemo(memo); if (!StringUtils.isBlank(memo)) {
} agentService.setTransmemo(memo);
agentService.setTrans(true); }
agentService.setTranstime(new Date()); agentService.setTrans(true);
agentServiceRes.save(agentService) ; agentService.setTranstime(new Date());
} agentServiceRes.save(agentService);
} }
}
return request(super.createRequestPageTempletResponse("redirect:/service/current/index.html")) ;
}
@RequestMapping("/current/end")
@Menu(type = "service" , subtype = "current" , admin= true)
public ModelAndView end(ModelMap map , HttpServletRequest request , @Valid String id) throws Exception {
if(!StringUtils.isBlank(id)){
AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request)) ;
if(agentService!=null){
User user = super.getUser(request);
AgentUser agentUser = agentUserRepository.findByIdAndOrgi(agentService.getAgentuserid(), super.getOrgi(request));
if(agentUser!=null){
AutomaticServiceDist.deleteAgentUser(agentUser, user.getOrgi());
}
agentService.setStatus(MainContext.AgentUserStatusEnum.END.toString());
agentServiceRes.save(agentService) ;
}
}
return request(super.createRequestPageTempletResponse("redirect:/service/current/index.html")); return request(super.createRequestPageTempletResponse("redirect:/service/current/index.html"));
} }
@RequestMapping("/current/invite") @RequestMapping("/current/end")
@Menu(type = "service" , subtype = "current" , admin= true) @Menu(type = "service", subtype = "current", admin = true)
public ModelAndView currentinvite(ModelMap map , HttpServletRequest request , @Valid String id) throws Exception { public ModelAndView end(ModelMap map, HttpServletRequest request, @Valid String id) throws Exception {
if(!StringUtils.isBlank(id)){ if (!StringUtils.isBlank(id)) {
AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request)) ; AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request));
if(agentService!=null){ if (agentService != null) {
User user = super.getUser(request); User user = super.getUser(request);
if(StringUtils.isBlank(agentService.getAgentno())) { AgentUser agentUser = agentUserRepository.findByIdAndOrgi(agentService.getAgentuserid(), super.getOrgi(request));
AiUser aiUser = (AiUser) CacheHelper.getOnlineUserCacheBean().getCacheObject(agentService.getSessionid(), agentService.getOrgi()) ; if (agentUser != null) {
IP ipdata = null ; AutomaticServiceDist.deleteAgentUser(agentUser, user.getOrgi());
if(aiUser != null ) { }
ipdata = aiUser.getIpdata() ; agentService.setStatus(MainContext.AgentUserStatusEnum.END.toString());
OnlineUserUtils.newRequestMessage(aiUser.getUserid() , aiUser.getUsername(), user.getOrgi(), agentService.getSessionid(), agentService.getAppid() , agentService.getIpaddr(), agentService.getOsname() , agentService.getBrowser() , "" , ipdata!=null ? ipdata : null , agentService.getChannel() , user.getOrgan(), user.getId() , null ,null, agentService.getContactsid(), MainContext.ChatInitiatorType.AGENT.toString() , aiUser.getContextid()) ; agentServiceRes.save(agentService);
} }
} }
}
}
return request(super.createRequestPageTempletResponse("redirect:/service/current/index.html")); return request(super.createRequestPageTempletResponse("redirect:/service/current/index.html"));
} }
@RequestMapping("/current/invite")
@RequestMapping("/quene/index") @Menu(type = "service", subtype = "current", admin = true)
@Menu(type = "service" , subtype = "filter" , admin= true) public ModelAndView currentinvite(ModelMap map, HttpServletRequest request, @Valid String id) throws Exception {
public ModelAndView quene(ModelMap map , HttpServletRequest request) { if (!StringUtils.isBlank(id)) {
Page<AgentUser> agentUserList = agentUserRes.findByOrgiAndStatus(super.getOrgi(request), MainContext.AgentUserStatusEnum.INQUENE.toString() ,new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime")) ; AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request));
List<String> skillList = new ArrayList<String>(); if (agentService != null) {
for(AgentUser agentUser : agentUserList.getContent()){ User user = super.getUser(request);
agentUser.setWaittingtime((int) (System.currentTimeMillis() - agentUser.getCreatetime().getTime())); if (StringUtils.isBlank(agentService.getAgentno())) {
if(!StringUtils.isBlank(agentUser.getSkill())){ AiUser aiUser = (AiUser) CacheHelper.getOnlineUserCacheBean().getCacheObject(agentService.getSessionid(), agentService.getOrgi());
skillList.add(agentUser.getSkill()) ; IP ipdata = null;
} if (aiUser != null) {
} ipdata = aiUser.getIpdata();
if(skillList.size() > 0){ OnlineUserUtils.newRequestMessage(aiUser.getUserid(), aiUser.getUsername(), user.getOrgi(), agentService.getSessionid(), agentService.getAppid(), agentService.getIpaddr(), agentService.getOsname(), agentService.getBrowser(), "", ipdata != null ? ipdata : null, agentService.getChannel(), user.getOrgan(), user.getId(), null, null, agentService.getContactsid(), MainContext.ChatInitiatorType.AGENT.toString(), aiUser.getContextid());
List<Organ> organList = organRes.findAll(skillList) ; }
for(AgentUser agentUser : agentUserList.getContent()){ }
if(!StringUtils.isBlank(agentUser.getSkill())){ }
for(Organ organ : organList){ }
if(agentUser.getSkill().equals(organ.getId())){ return request(super.createRequestPageTempletResponse("redirect:/service/current/index.html"));
agentUser.setSkillname(organ.getName()); }
break ;
}
} @RequestMapping("/quene/index")
} @Menu(type = "service", subtype = "filter", admin = true)
} public ModelAndView quene(ModelMap map, HttpServletRequest request) {
} Page<AgentUser> agentUserList = agentUserRes.findByOrgiAndStatus(super.getOrgi(request), MainContext.AgentUserStatusEnum.INQUENE.toString(), new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime"));
map.put("agentUserList", agentUserList) ; List<String> skillList = new ArrayList<String>();
for (AgentUser agentUser : agentUserList.getContent()) {
agentUser.setWaittingtime((int) (System.currentTimeMillis() - agentUser.getCreatetime().getTime()));
if (!StringUtils.isBlank(agentUser.getSkill())) {
skillList.add(agentUser.getSkill());
}
}
if (skillList.size() > 0) {
List<Organ> organList = organRes.findAll(skillList);
for (AgentUser agentUser : agentUserList.getContent()) {
if (!StringUtils.isBlank(agentUser.getSkill())) {
for (Organ organ : organList) {
if (agentUser.getSkill().equals(organ.getId())) {
agentUser.setSkillname(organ.getName());
break;
}
}
}
}
}
map.put("agentUserList", agentUserList);
return request(super.createAppsTempletResponse("/apps/service/quene/index")); return request(super.createAppsTempletResponse("/apps/service/quene/index"));
} }
@RequestMapping("/quene/clean") @RequestMapping("/quene/clean")
@Menu(type = "service" , subtype = "queneclean" , admin= true) @Menu(type = "service", subtype = "queneclean", admin = true)
public ModelAndView clean(ModelMap map , HttpServletRequest request ,@Valid String id) { public ModelAndView clean(ModelMap map, HttpServletRequest request, @Valid String id) {
AgentUser agentUser = agentUserRes.findByIdAndOrgi(id, super.getOrgi(request)) ; AgentUser agentUser = agentUserRes.findByIdAndOrgi(id, super.getOrgi(request));
if(agentUser!=null && agentUser.getStatus().equals(MainContext.AgentUserStatusEnum.INQUENE.toString())){ if (agentUser != null && agentUser.getStatus().equals(MainContext.AgentUserStatusEnum.INQUENE.toString())) {
agentUser.setAgent(null); agentUser.setAgent(null);
agentUser.setSkill(null); agentUser.setSkill(null);
agentUserRes.save(agentUser) ; agentUserRes.save(agentUser);
CacheHelper.getAgentUserCacheBean().put(agentUser.getUserid(), agentUser, super.getOrgi(request)); CacheHelper.getAgentUserCacheBean().put(agentUser.getUserid(), agentUser, super.getOrgi(request));
AutomaticServiceDist.allotAgent(agentUser, super.getOrgi(request)) ; AutomaticServiceDist.allotAgent(agentUser, super.getOrgi(request));
} }
return request(super.createRequestPageTempletResponse("redirect:/service/quene/index.html")); return request(super.createRequestPageTempletResponse("redirect:/service/quene/index.html"));
} }
@RequestMapping("/quene/invite") @RequestMapping("/quene/invite")
@Menu(type = "service" , subtype = "invite" , admin= true) @Menu(type = "service", subtype = "invite", admin = true)
public ModelAndView invite(ModelMap map , HttpServletRequest request ,@Valid String id) throws Exception { public ModelAndView invite(ModelMap map, HttpServletRequest request, @Valid String id) throws Exception {
AgentUser agentUser = agentUserRes.findByIdAndOrgi(id, super.getOrgi(request)) ; AgentUser agentUser = agentUserRes.findByIdAndOrgi(id, super.getOrgi(request));
if(agentUser!=null && agentUser.getStatus().equals(MainContext.AgentUserStatusEnum.INQUENE.toString())){ if (agentUser != null && agentUser.getStatus().equals(MainContext.AgentUserStatusEnum.INQUENE.toString())) {
AutomaticServiceDist.allotAgentForInvite(super.getUser(request).getId() , agentUser, super.getOrgi(request)) ; AutomaticServiceDist.allotAgentForInvite(super.getUser(request).getId(), agentUser, super.getOrgi(request));
} }
return request(super.createRequestPageTempletResponse("redirect:/service/quene/index.html")); return request(super.createRequestPageTempletResponse("redirect:/service/quene/index.html"));
} }
@RequestMapping("/agent/index") @RequestMapping("/agent/index")
@Menu(type = "service" , subtype = "onlineagent" , admin= true) @Menu(type = "service", subtype = "onlineagent", admin = true)
public ModelAndView agent(ModelMap map , HttpServletRequest request) { public ModelAndView agent(ModelMap map, HttpServletRequest request) {
List<AgentStatus> agentStatusList = agentStatusRepository.findByOrgi(super.getOrgi(request)) ; List<AgentStatus> agentStatusList = agentStatusRepository.findByOrgi(super.getOrgi(request));
for(int i=0 ; i<agentStatusList.size() ; ){ for (int i = 0; i < agentStatusList.size(); ) {
AgentStatus agentStatus = agentStatusList.get(i) ; AgentStatus agentStatus = agentStatusList.get(i);
if(CacheHelper.getAgentStatusCacheBean().getCacheObject(agentStatus.getAgentno(), super.getOrgi(request))==null) { if (CacheHelper.getAgentStatusCacheBean().getCacheObject(agentStatus.getAgentno(), super.getOrgi(request)) == null) {
agentStatusRepository.delete(agentStatus); agentStatusRepository.delete(agentStatus);
agentStatusList.remove(i) ; agentStatusList.remove(i);
continue ; continue;
}else{ } else {
AgentStatus temp = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(agentStatus.getAgentno(), super.getOrgi(request)) ; AgentStatus temp = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(agentStatus.getAgentno(), super.getOrgi(request));
agentStatusList.set(i, temp) ; agentStatusList.set(i, temp);
} }
i++ ; i++;
} }
List<String> skillList = new ArrayList<String>(); List<String> skillList = new ArrayList<String>();
for(AgentStatus agentStatus : agentStatusList){ for (AgentStatus agentStatus : agentStatusList) {
if(!StringUtils.isBlank(agentStatus.getSkill())){ if (!StringUtils.isBlank(agentStatus.getSkill())) {
skillList.add(agentStatus.getSkill()) ; skillList.add(agentStatus.getSkill());
} }
} }
if(skillList.size() > 0){ if (skillList.size() > 0) {
List<Organ> organList = organRes.findAll(skillList) ; List<Organ> organList = organRes.findAll(skillList);
for(AgentStatus agentStatus : agentStatusList){ for (AgentStatus agentStatus : agentStatusList) {
if(!StringUtils.isBlank(agentStatus.getSkill())){ if (!StringUtils.isBlank(agentStatus.getSkill())) {
for(Organ organ : organList){ for (Organ organ : organList) {
if(agentStatus.getSkill().equals(organ.getId())){ if (agentStatus.getSkill().equals(organ.getId())) {
agentStatus.setSkillname(organ.getName()); agentStatus.setSkillname(organ.getName());
break ; break;
} }
} }
} }
} }
} }
map.put("agentStatusList", agentStatusList) ; map.put("agentStatusList", agentStatusList);
return request(super.createAppsTempletResponse("/apps/service/agent/index")); return request(super.createAppsTempletResponse("/apps/service/agent/index"));
} }
@RequestMapping("/agent/offline") @RequestMapping("/agent/offline")
@Menu(type = "service" , subtype = "offline" , admin= true) @Menu(type = "service", subtype = "offline", admin = true)
public ModelAndView offline(ModelMap map , HttpServletRequest request , @Valid String id) { public ModelAndView offline(ModelMap map, HttpServletRequest request, @Valid String id) {
AgentStatus agentStatus = agentStatusRepository.findByIdAndOrgi(id, super.getOrgi(request)); AgentStatus agentStatus = agentStatusRepository.findByIdAndOrgi(id, super.getOrgi(request));
if(agentStatus!=null){ if (agentStatus != null) {
agentStatusRepository.delete(agentStatus); agentStatusRepository.delete(agentStatus);
} }
CacheHelper.getAgentStatusCacheBean().delete(agentStatus.getAgentno(), super.getOrgi(request));; CacheHelper.getAgentStatusCacheBean().delete(agentStatus.getAgentno(), super.getOrgi(request));
AutomaticServiceDist.publishMessage(super.getOrgi(request) , "agent" , "offline" , super.getUser(request).getId()); ;
AutomaticServiceDist.publishMessage(super.getOrgi(request), "agent", "offline", super.getUser(request).getId());
return request(super.createRequestPageTempletResponse("redirect:/service/agent/index.html")); return request(super.createRequestPageTempletResponse("redirect:/service/agent/index.html"));
} }
/**
* 非管理员坐席 /**
* @param map * 非管理员坐席
* @param request *
* @return * @param map
*/ * @param request
@RequestMapping("/user/index") * @return
@Menu(type = "service" , subtype = "userlist" , admin= true) */
public ModelAndView user(ModelMap map , HttpServletRequest request) { @RequestMapping("/user/index")
Page<User> userList = null; @Menu(type = "service", subtype = "userlist", admin = true)
if(super.isTenantshare()) { public ModelAndView user(ModelMap map, HttpServletRequest request) {
List<String> organIdList = new ArrayList<>(); Page<User> userList = null;
List<OrgiSkillRel> orgiSkillRelList = orgiSkillRelService.findByOrgi(super.getOrgi(request)) ; if (super.isTenantshare()) {
if(!orgiSkillRelList.isEmpty()) { List<String> organIdList = new ArrayList<>();
for(OrgiSkillRel rel:orgiSkillRelList) { List<OrgiSkillRel> orgiSkillRelList = orgiSkillRelService.findByOrgi(super.getOrgi(request));
organIdList.add(rel.getSkillid()); if (!orgiSkillRelList.isEmpty()) {
} for (OrgiSkillRel rel : orgiSkillRelList) {
} organIdList.add(rel.getSkillid());
userList=userRes.findByOrganInAndAgentAndDatastatus(organIdList,true,false,new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime")); }
}else { }
userList=userRes.findByOrgiAndAgentAndDatastatus(super.getOrgi(request), true,false, new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime")) ; userList = userRes.findByOrganInAndAgentAndDatastatus(organIdList, true, false, new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime"));
} } else {
for(User user : userList.getContent()){ userList = userRes.findByOrgiAndAgentAndDatastatus(super.getOrgi(request), true, false, new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime"));
if(CacheHelper.getAgentStatusCacheBean().getCacheObject(user.getId(), super.getOrgi(request))!=null){ }
user.setOnline(true); for (User user : userList.getContent()) {
} if (CacheHelper.getAgentStatusCacheBean().getCacheObject(user.getId(), super.getOrgi(request)) != null) {
} user.setOnline(true);
map.put("userList", userList) ; }
}
map.put("userList", userList);
return request(super.createAppsTempletResponse("/apps/service/user/index")); return request(super.createAppsTempletResponse("/apps/service/user/index"));
} }
/**
* 管理员坐席 /**
* @param map * 管理员坐席
* @param request *
* @return * @param map
*/ * @param request
@RequestMapping("/adminagent/index") * @return
@Menu(type = "service" , subtype = "adminagentlist" , admin= true) */
public ModelAndView adminagent(ModelMap map , HttpServletRequest request) { @RequestMapping("/adminagent/index")
Page<User> userList = userRes.findByOrgidAndAgentAndDatastatusAndUsertype(super.getOrgid(request), true,false,"0", new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime")) ; @Menu(type = "service", subtype = "adminagentlist", admin = true)
for(User user : userList.getContent()){ public ModelAndView adminagent(ModelMap map, HttpServletRequest request) {
if(CacheHelper.getAgentStatusCacheBean().getCacheObject(user.getId(), super.getOrgi(request))!=null){ Page<User> userList = userRes.findByOrgidAndAgentAndDatastatusAndUsertype(super.getOrgid(request), true, false, "0", new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime"));
user.setOnline(true); for (User user : userList.getContent()) {
} if (CacheHelper.getAgentStatusCacheBean().getCacheObject(user.getId(), super.getOrgi(request)) != null) {
} user.setOnline(true);
map.put("userList", userList) ; }
}
map.put("userList", userList);
return request(super.createAppsTempletResponse("/apps/service/adminagent/index")); return request(super.createAppsTempletResponse("/apps/service/adminagent/index"));
} }
@RequestMapping("/leavemsg/index")
@Menu(type = "service" , subtype = "leavemsg" , admin= true) @RequestMapping("/leavemsg/index")
public ModelAndView leavemsg(ModelMap map , HttpServletRequest request) { @Menu(type = "service", subtype = "leavemsg", admin = true)
Page<LeaveMsg> leaveMsgList = leaveMsgRes.findByOrgi(super.getOrgi(request),new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime")) ; public ModelAndView leavemsg(ModelMap map, HttpServletRequest request) {
map.put("leaveMsgList", leaveMsgList) ; Page<LeaveMsg> leaveMsgList = leaveMsgRes.findByOrgi(super.getOrgi(request), new PageRequest(super.getP(request), super.getPs(request), Direction.DESC, "createtime"));
map.put("leaveMsgList", leaveMsgList);
return request(super.createAppsTempletResponse("/apps/service/leavemsg/index")); return request(super.createAppsTempletResponse("/apps/service/leavemsg/index"));
} }
@RequestMapping("/leavemsg/delete") @RequestMapping("/leavemsg/delete")
@Menu(type = "service" , subtype = "leavemsg" , admin= true) @Menu(type = "service", subtype = "leavemsg", admin = true)
public ModelAndView leavemsg(ModelMap map , HttpServletRequest request , @Valid String id) { public ModelAndView leavemsg(ModelMap map, HttpServletRequest request, @Valid String id) {
if(!StringUtils.isBlank(id)){ if (!StringUtils.isBlank(id)) {
leaveMsgRes.delete(id); leaveMsgRes.delete(id);
} }
return request(super.createRequestPageTempletResponse("redirect:/service/leavemsg/index.html")); return request(super.createRequestPageTempletResponse("redirect:/service/leavemsg/index.html"));
} }
} }

View File

@ -16,110 +16,190 @@
*/ */
package com.chatopera.cc.app.im.client; package com.chatopera.cc.app.im.client;
import java.util.List; import com.chatopera.cc.app.basic.MainContext;
import com.corundumstudio.socketio.SocketIOClient;
import com.chatopera.cc.app.basic.MainUtils; import com.chatopera.cc.app.basic.MainUtils;
import com.chatopera.cc.app.im.util.IMServiceUtils;
import com.chatopera.cc.app.schedule.WebIMAgentDispatcher;
import com.chatopera.cc.app.schedule.WebIMOnlineUserDispatcher;
import com.corundumstudio.socketio.SocketIOClient;
import com.google.gson.JsonObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
public class NettyClients { public class NettyClients {
private final Logger logger = LoggerFactory.getLogger(NettyClient.class); private final Logger logger = LoggerFactory.getLogger(NettyClient.class);
private static NettyClients clients = new NettyClients(); private static NettyClients clients = new NettyClients();
private NettyIMClient imClients = new NettyIMClient();
private NettyAgentClient agentClients = new NettyAgentClient();
private NettyIMClient entIMClients = new NettyIMClient();
private NettyCallCenterClient callCenterClients = new NettyCallCenterClient();
private NettyCalloutClient calloutClients = new NettyCalloutClient();
private NettyChatbotClient chatbotClients = new NettyChatbotClient();
public int size(){
return imClients.size();
}
public static NettyClients getInstance(){
return clients ;
}
public NettyCallCenterClient getCallCenterClients(){
return this.callCenterClients ;
}
public void setImClients(NettyIMClient imClients) { private NettyIMClient imClients = new NettyIMClient();
this.imClients = imClients; private NettyAgentClient agentClients = new NettyAgentClient();
} private NettyIMClient entIMClients = new NettyIMClient();
public void putIMEventClient(String id , SocketIOClient userClient){ private NettyCallCenterClient callCenterClients = new NettyCallCenterClient();
imClients.putClient(id, userClient); private NettyCalloutClient calloutClients = new NettyCalloutClient();
} private NettyChatbotClient chatbotClients = new NettyChatbotClient();
public void closeIMEventClient(String id , String sessionid, String orgi){ public int size() {
List<SocketIOClient> userClients = imClients.getClients(id) ; return imClients.size();
for(SocketIOClient userClient : userClients){ }
if(MainUtils.getContextID(userClient.getSessionId().toString()).equals(sessionid)){
userClient.disconnect(); public static NettyClients getInstance() {
} return clients;
} }
}
public void removeIMEventClient(String id , String sessionid){ public NettyCallCenterClient getCallCenterClients() {
imClients.removeClient(id, sessionid); return this.callCenterClients;
} }
public void sendIMEventMessage(String id , String event , Object data){
List<SocketIOClient> userClients = imClients.getClients(id) ; /**
for(SocketIOClient userClient : userClients){ * 访客连接
userClient.sendEvent(event, data); */
} public void setImClients(NettyIMClient imClients) {
} this.imClients = imClients;
}
public void setAgentClients(NettyAgentClient agentClients) {
this.agentClients = agentClients; public void putIMEventClient(String id, SocketIOClient userClient) {
} imClients.putClient(id, userClient);
public void putAgentEventClient(String id , SocketIOClient agentClient){ }
agentClients.putClient(id, agentClient);
} public void closeIMEventClient(String id, String sessionid, String orgi) {
public void removeAgentEventClient(String id , String sessionid){ List<SocketIOClient> userClients = imClients.getClients(id);
agentClients.removeClient(id, sessionid); for (SocketIOClient userClient : userClients) {
} if (MainUtils.getContextID(userClient.getSessionId().toString()).equals(sessionid)) {
public void sendAgentEventMessage(String id , String event , Object data){ userClient.disconnect();
List<SocketIOClient> agents = agentClients.getClients(id) ; }
for(SocketIOClient agentClient : agents){ }
agentClient.sendEvent(event, data); }
}
} public void removeIMEventClient(String id, String sessionid) {
imClients.removeClient(id, sessionid);
public void setEntImClients(NettyIMClient entIMClients) { }
this.entIMClients = entIMClients;
} public void publishIMEventMessage(final String id, final String event, Serializable data) {
public void putEntIMEventClient(String id , SocketIOClient userClient){ // 检测client是否在这台机器上
entIMClients.putClient(id, userClient); if (!sendIMEventMessage(id, event, data)) {
} try {
public void removeEntIMEventClient(String id , String sessionid){ JsonObject payload = new JsonObject();
entIMClients.removeClient(id, sessionid); payload.addProperty("event", event);
} payload.addProperty("id", id);
public void sendEntIMEventMessage(String id , String event , Object data){ payload.addProperty("data", IMServiceUtils.serialize(data));
List<SocketIOClient> entims = entIMClients.getClients(id) ; MainContext.getContext().getBean(WebIMOnlineUserDispatcher.class).publish(payload);
for(SocketIOClient userClient : entims){ } catch (IOException e) {
userClient.sendEvent(event, data); logger.error("publishIMEventMessage", e);
} }
} }
public int getEntIMClientsNum(String user){ }
return entIMClients.getClients(user)!=null ? entIMClients.getClients(user).size() : 0;
} public boolean sendIMEventMessage(final String id, final String event, Object data) {
List<SocketIOClient> userClients = imClients.getClients(id);
public void sendCallCenterMessage(String id , String event , Object data){ for (SocketIOClient userClient : userClients) {
List<SocketIOClient> ccClients = callCenterClients.getClients(id) ; userClient.sendEvent(event, data);
for(SocketIOClient ccClient : ccClients){ }
ccClient.sendEvent(event, data); return userClients.size() > 0;
} }
}
/**
* 坐席连接
*/
public void setAgentClients(NettyAgentClient agentClients) {
this.agentClients = agentClients;
}
public void putAgentEventClient(String id, SocketIOClient agentClient) {
agentClients.putClient(id, agentClient);
}
public void removeAgentEventClient(String id, String sessionid) {
agentClients.removeClient(id, sessionid);
}
// publish to Redis
public void publishAgentEventMessage(String id, String event, Serializable data) {
// 检测client是否在这台机器上
if (!sendAgentEventMessage(id, event, data)) {
try {
JsonObject payload = new JsonObject();
payload.addProperty("event", event);
payload.addProperty("id", id);
payload.addProperty("data", IMServiceUtils.serialize(data));
MainContext.getContext().getBean(WebIMAgentDispatcher.class).publish(payload);
} catch (IOException e) {
logger.error("publishAgentEventMessage", e);
}
}
}
// 向坐席发送消息
public boolean sendAgentEventMessage(String id, String event, Object data) {
List<SocketIOClient> agents = agentClients.getClients(id);
for (SocketIOClient agentClient : agents) {
agentClient.sendEvent(event, data);
}
return agents.size() > 0;
}
/**
* 企业聊天
*/
public void setEntImClients(NettyIMClient entIMClients) {
this.entIMClients = entIMClients;
}
public void putEntIMEventClient(String id, SocketIOClient userClient) {
entIMClients.putClient(id, userClient);
}
public void removeEntIMEventClient(String id, String sessionid) {
entIMClients.removeClient(id, sessionid);
}
public void sendEntIMEventMessage(String id, String event, Object data) {
List<SocketIOClient> entims = entIMClients.getClients(id);
for (SocketIOClient userClient : entims) {
userClient.sendEvent(event, data);
}
}
public int getEntIMClientsNum(String user) {
return entIMClients.getClients(user) != null ? entIMClients.getClients(user).size() : 0;
}
public void sendCallCenterMessage(String id, String event, Object data) {
List<SocketIOClient> ccClients = callCenterClients.getClients(id);
for (SocketIOClient ccClient : ccClients) {
ccClient.sendEvent(event, data);
}
}
/**
* Callout Event Server Methods.
*/
public void putCalloutEventClient(String id, SocketIOClient client) {
calloutClients.putClient(id, client);
}
public void removeCalloutEventClient(String id, String sessionId) {
calloutClients.removeClient(id, sessionId);
}
public void sendCalloutEventMessage(String id, String event, Object data) {
List<SocketIOClient> _clients = calloutClients.getClients(id);
logger.info("sendCalloutEventMessage get clients size {}", _clients.size());
for (SocketIOClient c : _clients) {
c.sendEvent(event, data);
}
}
/** /**
* Chatbot Event Server Methods. * Chatbot Event Server Methods.
*/ */
public void putChatbotEventClient(String id, SocketIOClient client){ public void putChatbotEventClient(String id, SocketIOClient client) {
chatbotClients.putClient(id, client); chatbotClients.putClient(id, client);
} }
@ -127,29 +207,10 @@ public class NettyClients {
chatbotClients.removeClient(id, sessionId); chatbotClients.removeClient(id, sessionId);
} }
public void sendChatbotEventMessage(String id, String event, Object data){ public void sendChatbotEventMessage(String id, String event, Object data) {
List<SocketIOClient> _clients = chatbotClients.getClients(id); List<SocketIOClient> _clients = chatbotClients.getClients(id);
logger.info("sendChatbotEventMessage get clients size {}", _clients.size()); logger.info("sendChatbotEventMessage get clients size {}", _clients.size());
for(SocketIOClient c: _clients){ for (SocketIOClient c : _clients) {
c.sendEvent(event, data);
}
}
/**
* Callout Event Server Methods.
*/
public void putCalloutEventClient(String id, SocketIOClient client){
calloutClients.putClient(id, client);
}
public void removeCalloutEventClient(String id, String sessionId) {
calloutClients.removeClient(id, sessionId);
}
public void sendCalloutEventMessage(String id, String event, Object data){
List<SocketIOClient> _clients = calloutClients.getClients(id);
logger.info("sendCalloutEventMessage get clients size {}", _clients.size());
for(SocketIOClient c: _clients){
c.sendEvent(event, data); c.sendEvent(event, data);
} }
} }

View File

@ -16,228 +16,212 @@
*/ */
package com.chatopera.cc.app.im.handler; package com.chatopera.cc.app.im.handler;
import java.net.InetSocketAddress;
import java.util.Date;
import java.util.List;
import com.chatopera.cc.app.algorithm.AutomaticServiceDist; import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
import com.chatopera.cc.app.basic.MainContext; import com.chatopera.cc.app.basic.MainContext;
import com.chatopera.cc.app.basic.MainUtils; import com.chatopera.cc.app.basic.MainUtils;
import com.chatopera.cc.app.im.client.NettyClients;
import com.chatopera.cc.app.cache.CacheHelper; import com.chatopera.cc.app.cache.CacheHelper;
import com.chatopera.cc.app.im.router.OutMessageRouter; import com.chatopera.cc.app.im.client.NettyClients;
import com.chatopera.cc.app.im.message.AgentServiceMessage; import com.chatopera.cc.app.im.message.AgentServiceMessage;
import com.chatopera.cc.app.im.message.AgentStatusMessage; import com.chatopera.cc.app.im.message.AgentStatusMessage;
import com.chatopera.cc.app.im.message.ChatMessage; import com.chatopera.cc.app.im.message.ChatMessage;
import org.apache.commons.lang.StringUtils; import com.chatopera.cc.app.im.router.OutMessageRouter;
import org.springframework.beans.factory.annotation.Autowired; import com.chatopera.cc.app.model.*;
import com.chatopera.cc.app.persistence.repository.*;
import com.corundumstudio.socketio.AckRequest; import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient; import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer; import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect; import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect; import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent; import com.corundumstudio.socketio.annotation.OnEvent;
import com.chatopera.cc.app.persistence.repository.AgentStatusRepository; import org.apache.commons.lang.StringUtils;
import com.chatopera.cc.app.persistence.repository.AgentUserRepository; import org.springframework.beans.factory.annotation.Autowired;
import com.chatopera.cc.app.persistence.repository.AgentUserTaskRepository;
import com.chatopera.cc.app.persistence.repository.ChatMessageRepository; import java.net.InetSocketAddress;
import com.chatopera.cc.app.persistence.repository.WorkSessionRepository; import java.util.Date;
import com.chatopera.cc.app.model.AgentStatus; import java.util.List;
import com.chatopera.cc.app.model.AgentUser;
import com.chatopera.cc.app.model.AgentUserTask; public class AgentEventHandler {
import com.chatopera.cc.app.model.MessageOutContent; protected SocketIOServer server;
import com.chatopera.cc.app.model.WorkSession;
@Autowired
public class AgentEventHandler public AgentEventHandler(SocketIOServer server) {
{ this.server = server;
protected SocketIOServer server;
@Autowired
public AgentEventHandler(SocketIOServer server)
{
this.server = server ;
}
@OnConnect
public void onConnect(SocketIOClient client)
{
String user = client.getHandshakeData().getSingleUrlParam("userid") ;
String orgi = client.getHandshakeData().getSingleUrlParam("orgi") ;
String session = client.getHandshakeData().getSingleUrlParam("session") ;
String admin = client.getHandshakeData().getSingleUrlParam("admin") ;
if(!StringUtils.isBlank(user) && !StringUtils.isBlank(user)){
client.set("agentno", user);
AgentStatusRepository agentStatusRepository = MainContext.getContext().getBean(AgentStatusRepository.class) ;
List<AgentStatus> agentStatusList = agentStatusRepository.findByAgentnoAndOrgi(user , orgi);
if(agentStatusList.size() > 0){
AgentStatus agentStatus = agentStatusList.get(0) ;
agentStatus.setUpdatetime(new Date());
agentStatusRepository.save(agentStatus);
if(CacheHelper.getAgentStatusCacheBean().getCacheObject(user, orgi)!=null) {
CacheHelper.getAgentStatusCacheBean().put(user, agentStatus , orgi);
}
}
InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress() ;
String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString()) ;
WorkSessionRepository workSessionRepository = MainContext.getContext().getBean(WorkSessionRepository.class) ;
int count = workSessionRepository.countByAgentAndDatestrAndOrgi(user, MainUtils.simpleDateFormat.format(new Date()), orgi) ;
workSessionRepository.save(MainUtils.createWorkSession(user, MainUtils.getContextID(client.getSessionId().toString()), session, orgi, ip, address.getHostName() , admin , count == 0)) ;
NettyClients.getInstance().putAgentEventClient(user, client);
}
}
//添加@OnDisconnect事件客户端断开连接时调用刷新客户端信息
@OnDisconnect
public void onDisconnect(SocketIOClient client)
{
String user = client.getHandshakeData().getSingleUrlParam("userid") ;
String orgi = client.getHandshakeData().getSingleUrlParam("orgi") ;
String admin = client.getHandshakeData().getSingleUrlParam("admin") ;
if(!StringUtils.isBlank(user)){
AutomaticServiceDist.deleteAgentStatus(user, orgi, !StringUtils.isBlank(admin) && admin.equals("true"));
NettyClients.getInstance().removeAgentEventClient(user , MainUtils.getContextID(client.getSessionId().toString()));
WorkSessionRepository workSessionRepository = MainContext.getContext().getBean(WorkSessionRepository.class) ;
List<WorkSession> workSessionList = workSessionRepository.findByOrgiAndClientid(orgi, MainUtils.getContextID(client.getSessionId().toString())) ;
if(workSessionList.size() > 0) {
WorkSession workSession = workSessionList.get(0) ;
workSession.setEndtime(new Date());
if(workSession.getBegintime()!=null) {
workSession.setDuration((int) (System.currentTimeMillis() - workSession.getBegintime().getTime()));
}else if(workSession.getCreatetime()!=null) {
workSession.setDuration((int) (System.currentTimeMillis() - workSession.getCreatetime().getTime()));
}
if(workSession.isFirsttime()) {
workSession.setFirsttimes(workSession.getDuration());
}
workSessionRepository.save(workSession) ;
}
}
}
//消息接收入口当接收到消息后查找发送目标客户端并且向该客户端发送消息且给自己发送消息
@OnEvent(value = "service")
public void onEvent(SocketIOClient client, AckRequest request, AgentServiceMessage data)
{
}
//消息接收入口当接收到消息后查找发送目标客户端并且向该客户端发送消息且给自己发送消息
@OnEvent(value = "status")
public void onEvent(SocketIOClient client, AckRequest request, AgentStatusMessage data)
{
} }
//消息接收入口当接收到消息后查找发送目标客户端并且向该客户端发送消息且给自己发送消息 @OnConnect
@OnEvent(value = "message") public void onConnect(SocketIOClient client) {
public void onEvent(SocketIOClient client, AckRequest request, ChatMessage data) String user = client.getHandshakeData().getSingleUrlParam("userid");
{ String orgi = client.getHandshakeData().getSingleUrlParam("orgi");
String user = client.getHandshakeData().getSingleUrlParam("userid") ; String session = client.getHandshakeData().getSingleUrlParam("session");
AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(data.getTouser(), data.getOrgi()); String admin = client.getHandshakeData().getSingleUrlParam("admin");
MessageOutContent outMessage = new MessageOutContent() ; if (StringUtils.isNotBlank(user) && StringUtils.isNotBlank(user)) {
outMessage.setMessage(data.getMessage()); client.set("agentno", user);
if(MainContext.MediaTypeEnum.COOPERATION.toString().equals(data.getMsgtype())){ AgentStatusRepository agentStatusRepository = MainContext.getContext().getBean(AgentStatusRepository.class);
outMessage.setMessageType(MainContext.MediaTypeEnum.COOPERATION.toString()); List<AgentStatus> agentStatusList = agentStatusRepository.findByAgentnoAndOrgi(user, orgi);
}else{ if (agentStatusList.size() > 0) {
outMessage.setMessageType(MainContext.MediaTypeEnum.TEXT.toString()); AgentStatus agentStatus = agentStatusList.get(0);
} agentStatus.setUpdatetime(new Date());
agentStatusRepository.save(agentStatus);
outMessage.setAttachmentid(data.getAttachmentid()); if (CacheHelper.getAgentStatusCacheBean().getCacheObject(user, orgi) != null) {
CacheHelper.getAgentStatusCacheBean().put(user, agentStatus, orgi);
outMessage.setCalltype(MainContext.CallTypeEnum.OUT.toString()); }
outMessage.setAgentUser(agentUser); }
outMessage.setSnsAccount(null); InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress();
AgentStatus agentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(data.getUserid(), data.getOrgi()) ; String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString());
if(agentUser == null){
agentUser = MainContext.getContext().getBean(AgentUserRepository.class).findByIdAndOrgi(data.getTouser() , data.getOrgi()) ; WorkSessionRepository workSessionRepository = MainContext.getContext().getBean(WorkSessionRepository.class);
try { int count = workSessionRepository.countByAgentAndDatestrAndOrgi(user, MainUtils.simpleDateFormat.format(new Date()), orgi);
AutomaticServiceDist.serviceFinish(agentUser, data.getOrgi());
} catch (Exception e) { workSessionRepository.save(MainUtils.createWorkSession(user, MainUtils.getContextID(client.getSessionId().toString()), session, orgi, ip, address.getHostName(), admin, count == 0));
e.printStackTrace();
} NettyClients.getInstance().putAgentEventClient(user, client);
} }
}
if(agentUser!=null && user!=null && user.equals(agentUser.getAgentno())){
data.setId(MainUtils.getUUID()); //添加@OnDisconnect事件客户端断开连接时调用刷新客户端信息
data.setContextid(agentUser.getContextid()); @OnDisconnect
public void onDisconnect(SocketIOClient client) {
data.setAgentserviceid(agentUser.getAgentserviceid()); String user = client.getHandshakeData().getSingleUrlParam("userid");
data.setCreater(agentUser.getAgentno()); String orgi = client.getHandshakeData().getSingleUrlParam("orgi");
String admin = client.getHandshakeData().getSingleUrlParam("admin");
if(MainContext.MediaTypeEnum.COOPERATION.toString().equals(data.getMsgtype())){ if (StringUtils.isNotBlank(user)) {
data.setMsgtype(MainContext.MediaTypeEnum.COOPERATION.toString()); AutomaticServiceDist.deleteAgentStatus(user, orgi, StringUtils.isNotBlank(admin) && admin.equals("true"));
}else{ NettyClients.getInstance().removeAgentEventClient(user, MainUtils.getContextID(client.getSessionId().toString()));
data.setMsgtype(MainContext.MediaTypeEnum.TEXT.toString());
} WorkSessionRepository workSessionRepository = MainContext.getContext().getBean(WorkSessionRepository.class);
List<WorkSession> workSessionList = workSessionRepository.findByOrgiAndClientid(orgi, MainUtils.getContextID(client.getSessionId().toString()));
data.setCalltype(MainContext.CallTypeEnum.OUT.toString()); if (workSessionList.size() > 0) {
if(!StringUtils.isBlank(agentUser.getAgentno())){ WorkSession workSession = workSessionList.get(0);
data.setTouser(agentUser.getUserid()); workSession.setEndtime(new Date());
} if (workSession.getBegintime() != null) {
data.setChannel(agentUser.getChannel()); workSession.setDuration((int) (System.currentTimeMillis() - workSession.getBegintime().getTime()));
} else if (workSession.getCreatetime() != null) {
data.setUsession(agentUser.getUserid()); workSession.setDuration((int) (System.currentTimeMillis() - workSession.getCreatetime().getTime()));
}
outMessage.setContextid(agentUser.getContextid()); if (workSession.isFirsttime()) {
outMessage.setFromUser(data.getUserid()); workSession.setFirsttimes(workSession.getDuration());
outMessage.setToUser(data.getTouser()); }
outMessage.setChannelMessage(data); workSessionRepository.save(workSession);
if(agentStatus!=null){ }
data.setUsername(agentStatus.getUsername()); }
outMessage.setNickName(agentStatus.getUsername()); }
}else{
outMessage.setNickName(data.getUsername()); //消息接收入口当接收到消息后查找发送目标客户端并且向该客户端发送消息且给自己发送消息
} @OnEvent(value = "service")
outMessage.setCreatetime(data.getCreatetime()); public void onEvent(SocketIOClient client, AckRequest request, AgentServiceMessage data) {
AgentUserTaskRepository agentUserTaskRes = MainContext.getContext().getBean(AgentUserTaskRepository.class) ; }
AgentUserTask agentUserTask = agentUserTaskRes.getOne(agentUser.getId()) ;
//消息接收入口当接收到消息后查找发送目标客户端并且向该客户端发送消息且给自己发送消息
if(agentUserTask!=null){ @OnEvent(value = "status")
if(agentUserTask.getLastgetmessage() != null && agentUserTask.getLastmessage()!=null){ public void onEvent(SocketIOClient client, AckRequest request, AgentStatusMessage data) {
data.setLastagentmsgtime(agentUserTask.getLastgetmessage());
data.setLastmsgtime(agentUserTask.getLastmessage()); }
data.setAgentreplyinterval((int)((System.currentTimeMillis() - agentUserTask.getLastgetmessage().getTime())/1000)); //坐席上次回复消息的间隔
data.setAgentreplytime((int)((System.currentTimeMillis() - agentUserTask.getLastmessage().getTime())/1000)); //坐席回复消息花费时间 //消息接收入口当接收到消息后查找发送目标客户端并且向该客户端发送消息且给自己发送消息
} @OnEvent(value = "message")
public void onEvent(SocketIOClient client, AckRequest request, ChatMessage data) {
agentUserTask.setAgentreplys(agentUserTask.getAgentreplys()+1); //总咨询记录数量 String user = client.getHandshakeData().getSingleUrlParam("userid");
agentUserTask.setAgentreplyinterval(agentUserTask.getAgentreplyinterval() + data.getAgentreplyinterval()); //总时长 AgentUser agentUser = (AgentUser) CacheHelper.getAgentUserCacheBean().getCacheObject(data.getTouser(), data.getOrgi());
if(agentUserTask.getAgentreplys()>0){ MessageOutContent outMessage = new MessageOutContent();
agentUserTask.setAvgreplyinterval(agentUserTask.getAgentreplyinterval() / agentUserTask.getAgentreplys()); outMessage.setMessage(data.getMessage());
} if (MainContext.MediaTypeEnum.COOPERATION.toString().equals(data.getMsgtype())) {
outMessage.setMessageType(MainContext.MediaTypeEnum.COOPERATION.toString());
agentUserTask.setLastgetmessage(new Date()); } else {
outMessage.setMessageType(MainContext.MediaTypeEnum.TEXT.toString());
}
outMessage.setAttachmentid(data.getAttachmentid());
outMessage.setCalltype(MainContext.CallTypeEnum.OUT.toString());
outMessage.setAgentUser(agentUser);
outMessage.setSnsAccount(null);
AgentStatus agentStatus = (AgentStatus) CacheHelper.getAgentStatusCacheBean().getCacheObject(data.getUserid(), data.getOrgi());
if (agentUser == null) {
agentUser = MainContext.getContext().getBean(AgentUserRepository.class).findByIdAndOrgi(data.getTouser(), data.getOrgi());
try {
AutomaticServiceDist.serviceFinish(agentUser, data.getOrgi());
} catch (Exception e) {
e.printStackTrace();
}
}
if (agentUser != null && user != null && user.equals(agentUser.getAgentno())) {
data.setId(MainUtils.getUUID());
data.setContextid(agentUser.getContextid());
data.setAgentserviceid(agentUser.getAgentserviceid());
data.setCreater(agentUser.getAgentno());
if (MainContext.MediaTypeEnum.COOPERATION.toString().equals(data.getMsgtype())) {
data.setMsgtype(MainContext.MediaTypeEnum.COOPERATION.toString());
} else {
data.setMsgtype(MainContext.MediaTypeEnum.TEXT.toString());
}
data.setCalltype(MainContext.CallTypeEnum.OUT.toString());
if (StringUtils.isNotBlank(agentUser.getAgentno())) {
data.setTouser(agentUser.getUserid());
}
data.setChannel(agentUser.getChannel());
data.setUsession(agentUser.getUserid());
outMessage.setContextid(agentUser.getContextid());
outMessage.setFromUser(data.getUserid());
outMessage.setToUser(data.getTouser());
outMessage.setChannelMessage(data);
if (agentStatus != null) {
data.setUsername(agentStatus.getUsername());
outMessage.setNickName(agentStatus.getUsername());
} else {
outMessage.setNickName(data.getUsername());
}
outMessage.setCreatetime(data.getCreatetime());
AgentUserTaskRepository agentUserTaskRes = MainContext.getContext().getBean(AgentUserTaskRepository.class);
AgentUserTask agentUserTask = agentUserTaskRes.getOne(agentUser.getId());
if (agentUserTask != null) {
if (agentUserTask.getLastgetmessage() != null && agentUserTask.getLastmessage() != null) {
data.setLastagentmsgtime(agentUserTask.getLastgetmessage());
data.setLastmsgtime(agentUserTask.getLastmessage());
data.setAgentreplyinterval((int) ((System.currentTimeMillis() - agentUserTask.getLastgetmessage().getTime()) / 1000)); //坐席上次回复消息的间隔
data.setAgentreplytime((int) ((System.currentTimeMillis() - agentUserTask.getLastmessage().getTime()) / 1000)); //坐席回复消息花费时间
}
agentUserTask.setAgentreplys(agentUserTask.getAgentreplys() + 1); //总咨询记录数量
agentUserTask.setAgentreplyinterval(agentUserTask.getAgentreplyinterval() + data.getAgentreplyinterval()); //总时长
if (agentUserTask.getAgentreplys() > 0) {
agentUserTask.setAvgreplyinterval(agentUserTask.getAgentreplyinterval() / agentUserTask.getAgentreplys());
}
agentUserTask.setLastgetmessage(new Date());
// agentUserTask.setReptime(null); // agentUserTask.setReptime(null);
// agentUserTask.setReptimes("0"); // agentUserTask.setReptimes("0");
agentUserTaskRes.save(agentUserTask) ;
}
/**
* 保存消息
*/
MainContext.getContext().getBean(ChatMessageRepository.class).save(data) ;
client.sendEvent(MainContext.MessageTypeEnum.MESSAGE.toString(), data); agentUserTaskRes.save(agentUserTask);
}
if(!StringUtils.isBlank(data.getTouser())){
OutMessageRouter router = null ; /**
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel()) ; * 保存消息
if(router!=null){ */
router.handler(data.getTouser(), MainContext.MessageTypeEnum.MESSAGE.toString(), agentUser.getAppid(), outMessage); MainContext.getContext().getBean(ChatMessageRepository.class).save(data);
}
} client.sendEvent(MainContext.MessageTypeEnum.MESSAGE.toString(), data);
}else if(user!=null && agentUser!=null && !user.equals(agentUser.getAgentno())){
client.sendEvent(MainContext.MessageTypeEnum.END.toString(), agentUser); if (StringUtils.isNotBlank(data.getTouser())) {
} OutMessageRouter router = null;
} router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
if (router != null) {
router.handler(data.getTouser(), MainContext.MessageTypeEnum.MESSAGE.toString(), agentUser.getAppid(), outMessage);
}
}
} else if (user != null && agentUser != null && !user.equals(agentUser.getAgentno())) {
client.sendEvent(MainContext.MessageTypeEnum.END.toString(), agentUser);
}
}
} }

View File

@ -51,7 +51,7 @@ public class CalloutEventHandler
String admin = client.getHandshakeData().getSingleUrlParam("admin") ; String admin = client.getHandshakeData().getSingleUrlParam("admin") ;
logger.info("onConnect userid {}, orgi {}.", user, orgi); logger.info("onConnect userid {}, orgi {}.", user, orgi);
if(!StringUtils.isBlank(user) && !StringUtils.isBlank(user)){ if(StringUtils.isNotBlank(user) && StringUtils.isNotBlank(user)){
client.set("agentno", user); client.set("agentno", user);
InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress() ; InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress() ;
String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString()) ; String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString()) ;

View File

@ -58,7 +58,7 @@ public class MessageRouter extends Router {
if (agentService != null && MainContext.AgentUserStatusEnum.INSERVICE.toString().equals(agentService.getStatus())) { if (agentService != null && MainContext.AgentUserStatusEnum.INSERVICE.toString().equals(agentService.getStatus())) {
outMessage.setMessage(AutomaticServiceDist.getSuccessMessage(agentService, inMessage.getAgentUser().getChannel(), inMessage.getOrgi())); outMessage.setMessage(AutomaticServiceDist.getSuccessMessage(agentService, inMessage.getAgentUser().getChannel(), inMessage.getOrgi()));
// TODO #111 publish to redis // TODO #111 publish to redis
NettyClients.getInstance().sendAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), inMessage.getAgentUser()); NettyClients.getInstance().publishAgentEventMessage(agentService.getAgentno(), MainContext.MessageTypeEnum.NEW.toString(), inMessage.getAgentUser());
} else { } else {
if (agentService.getQueneindex() > 0) { //当前有坐席 if (agentService.getQueneindex() > 0) { //当前有坐席
outMessage.setMessage(AutomaticServiceDist.getQueneMessage(agentService.getQueneindex(), inMessage.getAgentUser().getChannel(), inMessage.getOrgi())); outMessage.setMessage(AutomaticServiceDist.getQueneMessage(agentService.getQueneindex(), inMessage.getAgentUser().getChannel(), inMessage.getOrgi()));

View File

@ -32,7 +32,7 @@ public class WebIMOutMessageRouter implements OutMessageRouter{
@Override @Override
public void handler(String touser, String msgtype, String appid, public void handler(String touser, String msgtype, String appid,
MessageOutContent outMessage) { MessageOutContent outMessage) {
NettyClients.getInstance().sendIMEventMessage(touser, msgtype, outMessage); NettyClients.getInstance().publishIMEventMessage(touser, msgtype, outMessage);
} }
} }

View File

@ -137,14 +137,14 @@ public class HumanUtils {
} }
} }
if (StringUtils.isNotBlank(data.getUserid()) && MainContext.MessageTypeEnum.MESSAGE.toString().equals(data.getType())) { if (StringUtils.isNotBlank(data.getUserid()) && MainContext.MessageTypeEnum.MESSAGE.toString().equals(data.getType())) {
NettyClients.getInstance().sendIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), outMessage); NettyClients.getInstance().publishIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), outMessage);
if (statusMessage != null) { if (statusMessage != null) {
NettyClients.getInstance().sendIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.STATUS.toString(), statusMessage); NettyClients.getInstance().publishIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.STATUS.toString(), statusMessage);
} }
} }
if (agentUser != null && StringUtils.isNotBlank(agentUser.getAgentno())) { if (agentUser != null && StringUtils.isNotBlank(agentUser.getAgentno())) {
//将消息发送给 坐席 // TODO 将消息发送给 坐席
NettyClients.getInstance().sendAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data); NettyClients.getInstance().publishAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
} }
} }
@ -176,7 +176,7 @@ public class HumanUtils {
// outMessage.setCreatetime(data.getCreatetime()); // outMessage.setCreatetime(data.getCreatetime());
// //
// if (!StringUtils.isBlank(data.getUserid()) && MainContext.MessageTypeEnum.MESSAGE.toString().equals(data.getType())) { // if (!StringUtils.isBlank(data.getUserid()) && MainContext.MessageTypeEnum.MESSAGE.toString().equals(data.getType())) {
// NettyClients.getInstance().sendIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), outMessage); // NettyClients.getInstance().publishIMEventMessage(data.getUserid(), MainContext.MessageTypeEnum.MESSAGE.toString(), outMessage);
// } // }
// } // }

View File

@ -8,6 +8,9 @@ import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.Base64;
public class IMServiceUtils { public class IMServiceUtils {
private final static Logger logger = LoggerFactory.getLogger(IMServiceUtils.class); private final static Logger logger = LoggerFactory.getLogger(IMServiceUtils.class);
@ -36,4 +39,30 @@ public class IMServiceUtils {
service.save(agentUser); service.save(agentUser);
CacheHelper.getAgentUserCacheBean().put(agentUser.getUserid(), agentUser, orgi); CacheHelper.getAgentUserCacheBean().put(agentUser.getUserid(), agentUser, orgi);
} }
/**
* Write the object to a Base64 string.
*/
public static String serialize(Serializable o) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
/**
* Read the object from Base64 string.
*/
public static Object deserialize(String s) throws IOException,
ClassNotFoundException {
byte[] data = Base64.getDecoder().decode(s);
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(data));
Object o = ois.readObject();
ois.close();
return o;
}
} }

View File

@ -20,143 +20,180 @@ package com.chatopera.cc.app.model;
import com.chatopera.cc.app.basic.MainContext; import com.chatopera.cc.app.basic.MainContext;
public class MessageInContent implements MessageDataBean{ public class MessageInContent implements MessageDataBean, java.io.Serializable {
public String id ; public String id;
private String nickName; private String nickName;
private String orgi ; private String orgi;
private String message ; private String message;
private String filename ; private String filename;
private int filesize ; private int filesize;
private String messageType; private String messageType;
private String fromUser; private String fromUser;
private String calltype = MainContext.CallTypeEnum.IN.toString() ; private String calltype = MainContext.CallTypeEnum.IN.toString();
private String toUser; private String toUser;
private SNSAccount snsAccount ; private SNSAccount snsAccount;
private AgentUser agentUser ; private AgentUser agentUser;
private Object channelMessage ; private Object channelMessage;
private String agentserviceid ; private String agentserviceid;
private String attachmentid ; private String attachmentid;
private boolean noagent ; private boolean noagent;
private Object user ; private Object user;
private String contextid ; private String contextid;
private String createtime ; private String createtime;
public String getId() { public String getId() {
return id; return id;
} }
public void setId(String id) {
this.id = id; public void setId(String id) {
} this.id = id;
public String getNickName() { }
return nickName;
} public String getNickName() {
public void setNickName(String nickName) { return nickName;
this.nickName = nickName; }
}
public String getOrgi() { public void setNickName(String nickName) {
return orgi; this.nickName = nickName;
} }
public void setOrgi(String orgi) {
this.orgi = orgi; public String getOrgi() {
} return orgi;
public String getMessage() { }
return message;
} public void setOrgi(String orgi) {
public void setMessage(String message) { this.orgi = orgi;
this.message = message; }
}
public String getMessageType() { public String getMessage() {
return messageType; return message;
} }
public void setMessageType(String messageType) {
this.messageType = messageType; public void setMessage(String message) {
} this.message = message;
public String getFromUser() { }
return fromUser;
} public String getMessageType() {
public void setFromUser(String fromUser) { return messageType;
this.fromUser = fromUser; }
}
public String getToUser() { public void setMessageType(String messageType) {
return toUser; this.messageType = messageType;
} }
public void setToUser(String toUser) {
this.toUser = toUser; public String getFromUser() {
} return fromUser;
public SNSAccount getSnsAccount() { }
return snsAccount;
} public void setFromUser(String fromUser) {
public void setSnsAccount(SNSAccount snsAccount) { this.fromUser = fromUser;
this.snsAccount = snsAccount; }
}
public AgentUser getAgentUser() { public String getToUser() {
return agentUser; return toUser;
} }
public void setAgentUser(AgentUser agentUser) {
this.agentUser = agentUser; public void setToUser(String toUser) {
} this.toUser = toUser;
public Object getChannelMessage() { }
return channelMessage;
} public SNSAccount getSnsAccount() {
public void setChannelMessage(Object channelMessage) { return snsAccount;
this.channelMessage = channelMessage; }
}
public Object getUser() { public void setSnsAccount(SNSAccount snsAccount) {
return user; this.snsAccount = snsAccount;
} }
public void setUser(Object user) {
this.user = user; public AgentUser getAgentUser() {
} return agentUser;
public String getContextid() { }
return contextid;
} public void setAgentUser(AgentUser agentUser) {
public void setContextid(String contextid) { this.agentUser = agentUser;
this.contextid = contextid; }
}
public String getCalltype() { public Object getChannelMessage() {
return calltype; return channelMessage;
} }
public void setCalltype(String calltype) {
this.calltype = calltype; public void setChannelMessage(Object channelMessage) {
} this.channelMessage = channelMessage;
public String getCreatetime() { }
return createtime;
} public Object getUser() {
public void setCreatetime(String createtime) { return user;
this.createtime = createtime; }
}
public String getFilename() { public void setUser(Object user) {
return filename; this.user = user;
} }
public void setFilename(String filename) {
this.filename = filename; public String getContextid() {
} return contextid;
public int getFilesize() { }
return filesize;
} public void setContextid(String contextid) {
public void setFilesize(int filesize) { this.contextid = contextid;
this.filesize = filesize; }
}
public String getAgentserviceid() { public String getCalltype() {
return agentserviceid; return calltype;
} }
public void setAgentserviceid(String agentserviceid) {
this.agentserviceid = agentserviceid; public void setCalltype(String calltype) {
} this.calltype = calltype;
public String getAttachmentid() { }
return attachmentid;
} public String getCreatetime() {
public void setAttachmentid(String attachmentid) { return createtime;
this.attachmentid = attachmentid; }
}
public boolean isNoagent() { public void setCreatetime(String createtime) {
return noagent; this.createtime = createtime;
} }
public void setNoagent(boolean noagent) {
this.noagent = noagent; public String getFilename() {
} return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public int getFilesize() {
return filesize;
}
public void setFilesize(int filesize) {
this.filesize = filesize;
}
public String getAgentserviceid() {
return agentserviceid;
}
public void setAgentserviceid(String agentserviceid) {
this.agentserviceid = agentserviceid;
}
public String getAttachmentid() {
return attachmentid;
}
public void setAttachmentid(String attachmentid) {
this.attachmentid = attachmentid;
}
public boolean isNoagent() {
return noagent;
}
public void setNoagent(boolean noagent) {
this.noagent = noagent;
}
} }

View File

@ -55,8 +55,6 @@ import java.util.List;
@Component @Component
public class CallOutWireTask implements MessageListener { public class CallOutWireTask implements MessageListener {
private static final Logger logger = LoggerFactory.getLogger(CallOutWireTask.class); private static final Logger logger = LoggerFactory.getLogger(CallOutWireTask.class);
private static final RedisSerializer<String> redisStringSerializer = new StringRedisSerializer();
@Autowired @Autowired
private CallOutDialplanRepository callOutDialplanRes; private CallOutDialplanRepository callOutDialplanRes;

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2018 Chatopera Inc, <https://www.chatopera.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chatopera.cc.app.schedule;
import com.chatopera.cc.app.im.client.NettyClients;
import com.chatopera.cc.app.im.util.IMServiceUtils;
import com.chatopera.cc.util.Constants;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.*;
import java.util.Base64;
/**
* 坐席消息分发
*/
@Component
public class WebIMAgentDispatcher implements MessageListener {
private final static Logger logger = LoggerFactory.getLogger(WebIMAgentDispatcher.class);
private ListOperations<String, String> redisListOps;
private HashOperations<String, String, String> redisHashOps;
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private String redisPort;
@Value("${spring.redis.database}")
private String redisDB;
@Value("${application.node.id}")
private String appNodeId;
/**
* 使用StringRedisTemplate而不是RedisTemplate解决序列化问题
* https://stackoverflow.com/questions/13215024/weird-redis-key-with-spring-data-jedis
*/
@Autowired
private StringRedisTemplate redis;
@PostConstruct
private void init() {
redisListOps = redis.opsForList();
redisHashOps = redis.opsForHash();
}
/**
* Publish Message into Channel with redis PubSub
*
* @param j
*/
public void publish(JsonObject j) {
ChannelTopic ct = new ChannelTopic(String.format(Constants.INSTANT_MESSTRING_WEBIM_AGENT_PATTERN, appNodeId));
j.addProperty("node", appNodeId);
redis.convertAndSend(ct.getTopic(), j.toString());
}
@Override
public void onMessage(Message message, byte[] bytes) {
logger.debug("[instant messaging] onMessage {}", message);
String payload = new String(message.getBody());
JsonParser parser = new JsonParser();
JsonObject j = parser.parse(payload).getAsJsonObject();
logger.debug("[instant messaging] message body {}", j.toString());
try {
NettyClients.getInstance().sendAgentEventMessage(j.get("id").getAsString(),
j.get("event").getAsString(),
IMServiceUtils.deserialize(j.get("data").getAsString()));
} catch (Exception e) {
logger.error("onMessage", e);
}
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2018 Chatopera Inc, <https://www.chatopera.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chatopera.cc.app.schedule;
import com.chatopera.cc.app.im.client.NettyClients;
import com.chatopera.cc.app.im.util.IMServiceUtils;
import com.chatopera.cc.util.Constants;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.*;
import java.util.Base64;
/**
* 访客消息分发
*/
@Component
public class WebIMOnlineUserDispatcher implements MessageListener {
private final static Logger logger = LoggerFactory.getLogger(WebIMOnlineUserDispatcher.class);
private ListOperations<String, String> redisListOps;
private HashOperations<String, String, String> redisHashOps;
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private String redisPort;
@Value("${spring.redis.database}")
private String redisDB;
@Value("${application.node.id}")
private String appNodeId;
/**
* 使用StringRedisTemplate而不是RedisTemplate解决序列化问题
* https://stackoverflow.com/questions/13215024/weird-redis-key-with-spring-data-jedis
*/
@Autowired
private StringRedisTemplate redis;
@PostConstruct
private void init() {
redisListOps = redis.opsForList();
redisHashOps = redis.opsForHash();
}
/**
* Publish Message into Channel with redis PubSub
*
* @param j
*/
public void publish(JsonObject j) {
ChannelTopic ct = new ChannelTopic(String.format(Constants.INSTANT_MESSTRING_WEBIM_ONLINE_USER_PATTERN, appNodeId));
j.addProperty("node", appNodeId);
redis.convertAndSend(ct.getTopic(), j.toString());
}
@Override
public void onMessage(Message message, byte[] bytes) {
logger.debug("[instant messaging] onMessage {}", message);
String payload = new String(message.getBody());
JsonParser parser = new JsonParser();
JsonObject j = parser.parse(payload).getAsJsonObject();
logger.debug("[instant messaging] message body {}", j.toString());
try {
NettyClients.getInstance().sendIMEventMessage(j.get("id").getAsString(),
j.get("event").getAsString(),
IMServiceUtils.deserialize(j.get("data").getAsString()));
} catch (Exception e) {
logger.error("onMessage", e);
}
}
}

View File

@ -15,25 +15,19 @@
*/ */
package com.chatopera.cc.app.schedule; package com.chatopera.cc.app.schedule;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import com.chatopera.cc.app.algorithm.AutomaticServiceDist; import com.chatopera.cc.app.algorithm.AutomaticServiceDist;
import com.chatopera.cc.app.basic.MainContext; import com.chatopera.cc.app.basic.MainContext;
import com.chatopera.cc.app.im.client.NettyClients;
import com.chatopera.cc.app.basic.MainUtils; import com.chatopera.cc.app.basic.MainUtils;
import com.chatopera.cc.exchange.DataExchangeInterface;
import com.chatopera.cc.util.freeswitch.model.CallCenterAgent;
import com.chatopera.cc.app.cache.CacheHelper; import com.chatopera.cc.app.cache.CacheHelper;
import com.chatopera.cc.app.persistence.impl.CallOutQuene; import com.chatopera.cc.app.im.client.NettyClients;
import com.chatopera.cc.app.persistence.repository.AgentUserTaskRepository;
import com.chatopera.cc.app.persistence.repository.JobDetailRepository;
import com.chatopera.cc.app.persistence.repository.OnlineUserRepository;
import com.chatopera.cc.util.OnlineUserUtils;
import com.chatopera.cc.app.im.router.OutMessageRouter;
import com.chatopera.cc.app.im.message.ChatMessage; import com.chatopera.cc.app.im.message.ChatMessage;
import com.chatopera.cc.app.im.router.OutMessageRouter;
import com.chatopera.cc.app.model.*;
import com.chatopera.cc.app.persistence.impl.CallOutQuene;
import com.chatopera.cc.app.persistence.repository.*;
import com.chatopera.cc.exchange.DataExchangeInterface;
import com.chatopera.cc.util.OnlineUserUtils;
import com.chatopera.cc.util.freeswitch.model.CallCenterAgent;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -43,18 +37,10 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import com.chatopera.cc.app.persistence.repository.ChatMessageRepository; import java.util.ArrayList;
import com.chatopera.cc.app.persistence.repository.ConsultInviteRepository; import java.util.Collection;
import com.chatopera.cc.app.model.AgentStatus; import java.util.Date;
import com.chatopera.cc.app.model.AgentUser; import java.util.List;
import com.chatopera.cc.app.model.AgentUserTask;
import com.chatopera.cc.app.model.AiConfig;
import com.chatopera.cc.app.model.AiUser;
import com.chatopera.cc.app.model.CousultInvite;
import com.chatopera.cc.app.model.JobDetail;
import com.chatopera.cc.app.model.MessageOutContent;
import com.chatopera.cc.app.model.OnlineUser;
import com.chatopera.cc.app.model.SessionConfig;
@Configuration @Configuration
@EnableScheduling @EnableScheduling
@ -72,7 +58,7 @@ public class WebIMTask {
@Autowired @Autowired
private TaskExecutor webimTaskExecutor; private TaskExecutor webimTaskExecutor;
@Scheduled(fixedDelay = 5000) // 每5秒执行一次 @Scheduled(fixedDelay = 5000) // 处理超时消息每5秒执行一次
public void task() { public void task() {
List<SessionConfig> sessionConfigList = AutomaticServiceDist.initSessionConfigList(); List<SessionConfig> sessionConfigList = AutomaticServiceDist.initSessionConfigList();
if (sessionConfigList != null && sessionConfigList.size() > 0 && MainContext.getContext() != null) { if (sessionConfigList != null && sessionConfigList.size() > 0 && MainContext.getContext() != null) {
@ -255,7 +241,7 @@ public class WebIMTask {
private void processMessage(SessionConfig sessionConfig, String message, String servicename, AgentUser agentUser, AgentStatus agentStatus, AgentUserTask task) { private void processMessage(SessionConfig sessionConfig, String message, String servicename, AgentUser agentUser, AgentStatus agentStatus, AgentUserTask task) {
MessageOutContent outMessage = new MessageOutContent(); MessageOutContent outMessage = new MessageOutContent();
if (!StringUtils.isBlank(message)) { if (StringUtils.isNotBlank(message)) {
outMessage.setMessage(message); outMessage.setMessage(message);
outMessage.setMessageType(MainContext.MediaTypeEnum.TEXT.toString()); outMessage.setMessageType(MainContext.MediaTypeEnum.TEXT.toString());
outMessage.setCalltype(MainContext.CallTypeEnum.OUT.toString()); outMessage.setCalltype(MainContext.CallTypeEnum.OUT.toString());
@ -279,7 +265,7 @@ public class WebIMTask {
data.setAgentserviceid(agentUser.getAgentserviceid()); data.setAgentserviceid(agentUser.getAgentserviceid());
data.setCalltype(MainContext.CallTypeEnum.OUT.toString()); data.setCalltype(MainContext.CallTypeEnum.OUT.toString());
if (!StringUtils.isBlank(agentUser.getAgentno())) { if (StringUtils.isNotBlank(agentUser.getAgentno())) {
data.setTouser(agentUser.getUserid()); data.setTouser(agentUser.getUserid());
} }
data.setChannel(agentUser.getChannel()); data.setChannel(agentUser.getChannel());
@ -304,11 +290,12 @@ public class WebIMTask {
*/ */
MainContext.getContext().getBean(ChatMessageRepository.class).save(data); MainContext.getContext().getBean(ChatMessageRepository.class).save(data);
if (agentUser != null && !StringUtils.isBlank(agentUser.getAgentno())) { //同时发送消息给双方 // 同时发送消息给双方
NettyClients.getInstance().sendAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data); if (agentUser != null && StringUtils.isNotBlank(agentUser.getAgentno())) {
NettyClients.getInstance().publishAgentEventMessage(agentUser.getAgentno(), MainContext.MessageTypeEnum.MESSAGE.toString(), data);
} }
if (!StringUtils.isBlank(data.getTouser())) { if (StringUtils.isNotBlank(data.getTouser())) {
OutMessageRouter router = null; OutMessageRouter router = null;
router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel()); router = (OutMessageRouter) MainContext.getContext().getBean(agentUser.getChannel());
if (router != null) { if (router != null) {

View File

@ -16,6 +16,7 @@
package com.chatopera.cc.util; package com.chatopera.cc.util;
import com.chatopera.cc.app.basic.MainContext; import com.chatopera.cc.app.basic.MainContext;
import org.apache.commons.lang.StringUtils;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -46,6 +47,17 @@ public class Constants {
public final static SimpleDateFormat DISPLAY_DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public final static SimpleDateFormat DISPLAY_DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public final static DecimalFormat DURATION_MINS_FORMATTER = new DecimalFormat("0.00"); public final static DecimalFormat DURATION_MINS_FORMATTER = new DecimalFormat("0.00");
/**
* Instant Messaging Events
*/
public final static String INSTANT_MESSTRING_WEBIM_AGENT_PATTERN = "im:webim:agent:%s:events";
public final static String INSTANT_MESSAGING_WEBIM_AGENT_CHANNEL = String.format(INSTANT_MESSTRING_WEBIM_AGENT_PATTERN, "*");
public final static String INSTANT_MESSTRING_WEBIM_ONLINE_USER_PATTERN = "im:webim:onlineuser:%s:events";
public final static String INSTANT_MESSAGING_WEBIM_ONLINE_USER_CHANNEL = String.format(INSTANT_MESSTRING_WEBIM_ONLINE_USER_PATTERN, "*");
/** /**
* FreeSwitch Communication * FreeSwitch Communication
*/ */

View File

@ -18,6 +18,8 @@
# 证书相关信息 # 证书相关信息
license.client.id=cskefu license.client.id=cskefu
application.version=3.9.0 application.version=3.9.0
# 在集群状态下每个Node都有自己唯一的ID
application.node.id=localhost
# security # security
management.security.enabled=false management.security.enabled=false
@ -131,7 +133,7 @@ spring.redis.port=6379
# Redis服务器连接密码默认为空 # Redis服务器连接密码默认为空
spring.redis.password= spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制) # 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=20 spring.redis.pool.max-active=-1
# 连接池最大阻塞等待时间(使用负值表示没有限制) # 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1 spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接 # 连接池中的最大空闲连接