spring框架整合websocket并带分组聊天功能的方法

websocket实现分组聊天

spring框架整合websocket的教程已经很多了,其中的例子都是简单的多人聊天,可以将消息发给指定的人或者全部人。不过我想发的消息只有部分人得到,但又不想挨个儿去发送,那么分组就有必要了。

先是常规的spring框架整合websocket流程

修改spring配置文件

spring配置文件位置在web.xml里的contextConfigLocation下一行;
因为我使用了ssm框架就没用tomcat支持的websocket方法了。
在spring的xml配置文件里开头的地方新增下面内容:

<beans 
	xmlns=xmlns:websocket="http://www.springframework.org/schema/websocket"
   	
   	xsi:schemaLocation="
    http://www.springframework.org/schema/websocket/spring-websocket.xsd">

在下面的context:component-scan标签里将websocket配置类的路径添加到base-package里。

在扫描路径下创建websocket配置类

import com.faker.app.service.MyWebSocketHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

/**
 * <p>Title: websocket配置类 - WebSocketConfig</p>
 *
 * <p>Description:websocket配置信息</p>
 *
 * <p>Copyright: Copyright Faker(c) 2018</p>
 *
 * <p>Company: 无</p>
 *
 * @author Anlinxi
 *
 * @version 1.0
 */
@Configuration
//这个标注可以不加,如果有加,要extends WebMvcConfigurerAdapter
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

    /**
     * 注册websocket的信息
     * @param registry registry
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //设置websocket的地址,注册Handler,注册Interceptor
        registry.addHandler(SocketHandler(), "/socketServer").addInterceptors(new HttpSessionHandshakeInterceptor());
        //注册SockJS,提供SockJS支持(主要是兼容ie8)
        registry.addHandler(SocketHandler(), "/sockjs/socketServer")
                //注册Interceptor
                .addInterceptors(new HttpSessionHandshakeInterceptor())
                //支持sockjs协议
                .withSockJS();
    }


    @Bean
    public WebSocketHandler SocketHandler(){
        return new MyWebSocketHandler();
    }


    /**
     * 配置webSocket引擎
     * 用于tomcat 可以不配置
     * @return Bean
     */
    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(8192);
        container.setMaxBinaryMessageBufferSize(8192);
        return container;
    }

}

继续建立WebSocketInterceptor拦截器对握手前后进行处理

import org.apache.log4j.Logger;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * <p>Title: WebSocketInterceptor拦截器 - WebSocketInterceptor</p>
 *
 * <p>Description:WebSocket 适配器 拦截器</p>
 *
 * <p>Copyright: Copyright Faker(c) 2018</p>
 *
 * <p>Company: 无</p>
 *
 * @author Anlinxi
 *
 * @version 1.0
 */
public class WebSocketInterceptor implements HandshakeInterceptor {

    /**
     * 日志
     */
    private final static Logger log= Logger.getLogger(WebSocketInterceptor.class);

    /**
     * 握手前
     * @param request 请求
     * @param response 响应
     * @param handler ws握手
     * @param attributes 属性
     * @return 是否握手成功
     * @throws Exception 异常
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
                                   Map<String, Object> attributes) throws Exception {
        log.info("执行握手: "+handler+"map: "+attributes.values());
        if(request != null){
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            HttpSession session = servletRequest.getServletRequest().getSession();
            String usergroup = servletRequest.getServletRequest().getParameter("WEBSOCKET_GROUP");
            if (usergroup != null) {
                session.setAttribute("SESSION_GROUP", usergroup);
                attributes.put("WEBSOCKET_GROUP", usergroup);
            }
            if(session!=null){
                String username = (String) session.getAttribute("WEBSOCKET_ID");
                if(username!=null){
                    session.setAttribute("SESSION_ID", username);
                    attributes.put("WEBSOCKET_ID", username);
                }else{
                    session.setAttribute("SESSION_ID", session.getId());
                    attributes.put("WEBSOCKET_ID", session.getId());
                }
            }
        }
        return true;
    }

    /**
     * 握手后
     * @param request 请求
     * @param response 响应
     * @param handler ws握手
     * @param exceptions 错误
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Exception exceptions) {
        log.info("握手后: "+handler+"exceptions: "+exceptions);
    }

}

最重要的分组功能是在Websocket处理器里的

通过一个Map来储存各个userList分组成员

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.*;
/**
 * <p>Title: Websocket处理器 - WebSocketHandler</p>
 *
 * <p>Description:统一发送信息等操作的</p>
 *
 * <p>Copyright: Copyright Faker(c) 2018</p>
 *
 * <p>Company: 无</p>
 *
 * @author Anlinxi
 *
 * @version 1.0
 */
public class WebSocketHandler extends TextWebSocketHandler {

    private final static Logger logger = LoggerFactory.getLogger(WebSocketHandler.class);

    //储存分组信息 分组名:用户分组list
    private static final Map<String,ArrayList<WebSocketSession>> userMap = new HashMap<>();

    /**
     * 处理前端发送的文本信息
     * js调用websocket.send时候,会调用该方法
     * @param session session
     * @param message 发送信息
     * @throws Exception 异常
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String username = (String) session.getAttributes().get("WEBSOCKET_ID");
        // 获取提交过来的消息详情
        logger.debug("收到用户 " + username + "的消息:" + message.toString());
        //回复一条信息,
        session.sendMessage(new TextMessage("回复信息:" + message.getPayload()));
    }


    /**
     * 当新连接建立的时候,被调用
     * 连接成功时候,会触发页面上onOpen方法
     * @param session session
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //已建立连接的用户
        ArrayList<WebSocketSession> users = new ArrayList<>();
        users.add(session);
        // 这块会实现自己业务,比如,当用户登录后,会把离线消息推送给用户
        String userId = (String) session.getAttributes().get("WEBSOCKET_ID");
        //已建立的用户分组
        String usergroup = (String) session.getAttributes().get("WEBSOCKET_GROUP");
        if(usergroup==null){
            userMap.put("",users);
        }else{
            userMap.put(usergroup,users);
        }
        logger.info(usergroup+"组下用户 " + userId + " 连接成功");
        session.sendMessage(new TextMessage(usergroup+"组下用户 " + userId + "连接成功"));
        session.sendMessage(new TextMessage("欢迎萌新~"));
    }

    /**
     * 当连接关闭时被调用
     * @param session session
     * @param status 连接状态
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String username = (String) session.getAttributes().get("WEBSOCKET_ID");
        //已建立的用户分组
        String usergroup = (String) session.getAttributes().get("WEBSOCKET_GROUP");
        ArrayList<WebSocketSession> userList  = userMap.get(usergroup);
        logger.info(usergroup+"组下用户 " + username + " 连接关闭. 状态: " + status);
        userList.remove(session);
        //当该组成员为空的时候,删除该组
        if(userList.size()<=0){
            userMap.remove(usergroup);
        }
    }

    /**
     * 传输错误时调用
     * @param session session
     * @param exception 异常
     * @throws Exception 异常
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        String username = (String) session.getAttributes().get("WEBSOCKET_ID");
        if (session.isOpen()) {
            session.close();
        }
        //已建立的用户分组
        String usergroup = (String) session.getAttributes().get("WEBSOCKET_GROUP");
        ArrayList<WebSocketSession> userList  = userMap.get(usergroup);
        logger.debug(usergroup+"组下用户 " + username +" websocket 连接传输错误......");
        userList.remove(session);
    }

    /**
     * 给所有在线用户发送消息
     * @param message 发送消息
     */
    public void sendMessageToUsers(TextMessage message) {
        //遍历组map
        Set<String> set = userMap.keySet();
        for (String key:set) {
            ArrayList<WebSocketSession> users = userMap.get(key);
            //遍历组下成员
            for (WebSocketSession user : users) {
                try {
                    if (user.isOpen()) {
                        user.sendMessage(message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 给某个用户发送消息
     * @param userId 用户id
     * @param message 发送信息
     */
    public void sendMessageToUser(String userId, TextMessage message) {
        //遍历组map
        Set<String> set = userMap.keySet();
        for (String key:set) {
            ArrayList<WebSocketSession> users = userMap.get(key);
            //遍历组下成员
            for (WebSocketSession user : users) {
                if (user.getAttributes().get("WEBSOCKET_ID").equals(userId)) {
                    try {
                        if (user.isOpen()) {
                            user.sendMessage(message);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
    }

    /**
     * 给某个组下所有用户发送消息
     * @param message 消息
     * @param groupName 分组
     */
    public void sendMessageToGroup(TextMessage message,String groupName) {
        if(groupName!=null){
            //取出该分组名下的用户列表
            ArrayList<WebSocketSession> userList = userMap.get(groupName);
            if(userList!=null&&userList.size()>0){
                for(WebSocketSession user:userList){
                    if (user.isOpen()) {
                        try {
                            user.sendMessage(message);
                        } catch (IOException e) {
                            logger.error("给用户"+user.getId()+"发送信息失败。");
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取当前用户id
     * @param session session
     * @return id
     */
    private String getClientId(WebSocketSession session) {
        try {
            return (String) session.getAttributes().get("WEBSOCKET_ID");
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取当前用户所在分组
     * @param session session
     * @return 分组名
     */
    private String getGroupName(WebSocketSession session) {
        try {
            return (String) session.getAttributes().get("WEBSOCKET_GROUP");
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取所有分组名称
     * @return 分组名称
     */
    public List<String>  getAllUserGroup() {
        //取出所有分组名称
        Set<String> set = userMap.keySet();
        //放入list内
        return new ArrayList<>(set);
    }

    /***
     * 取出该分组下用户信息
     * @param groupName 分组名称
     * @return 返回
     */
    public ArrayList<WebSocketSession> getGroupUserWebSocketSession(String groupName) {
        ArrayList<WebSocketSession> userList = new ArrayList<>(2);
        try {
            if(groupName!=null){
                 userList = userMap.get(groupName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return userList;
    }

}

后面几天有加了些内容… 重新发一份…

ToolsUtil.isNotNull就是判断字符串是否为null或者空,你也可以简单的用string !=null&&"".equals(string)来代替。

import com.faker.app.bo.AppUserBo;
import com.faker.app.util.ToolsUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.*;
/**
 * <p>Title: Websocket处理器 - WebSocketHandler</p>
 *
 * <p>Description:统一发送信息等操作的</p>
 *
 * <p>Copyright: Copyright Faker(c) 2018</p>
 *
 * <p>Company: 无</p>
 *
 * @author Anlinxi
 *
 * @version 1.0
 */
public class WebSocketHandler extends TextWebSocketHandler {

    private final static Logger logger = LoggerFactory.getLogger(WebSocketHandler.class);

    //储存分组信息 分组名:用户分组list
    private static final Map<String,ArrayList<WebSocketSession>> userMap = new HashMap<>();

    //实例化的类
    public static WebSocketHandler webSocketHandler;

    /**
     * 实例化方法
     * @return webSocketHandler
     */
    public static WebSocketHandler getBeans(){
        if(webSocketHandler == null){
            webSocketHandler = new WebSocketHandler();
        }
        return webSocketHandler;
    }

    /**
     * 处理前端发送的文本信息
     * js调用websocket.send时候,会调用该方法
     * @param session session
     * @param message 发送信息
     * @throws Exception 异常
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //获取用户id
        String userId = (String) session.getAttributes().get("WEBSOCKET_ID");
        //用户分组
        String usergroup = (String) session.getAttributes().get("WEBSOCKET_GROUP");
        //昵称
        String nickName = (String) session.getAttributes().get("WEBSOCKET_NICK_NAME");
        //消息
        AppUserBo appUserBo =  new AppUserBo(userId,nickName,usergroup,message.getPayload());
        // 获取提交过来的消息详情
        logger.debug("收到用户 " + userId + "的消息:" + message);
        if(ToolsUtil.isNullOrEmpty(message.getPayload())){
            //回复一条信息
            if(ToolsUtil.isNotNull(usergroup)){
                sendMessageToGroup(usergroup,appUserBo);
            }else{
                session.sendMessage(sendJsonMsg(appUserBo));
            }
            return;
        }
        if("{".equals(message.getPayload().substring(0,1))){
            Map<String,Object> map = new HashMap<>(1);
            try {
                map = JSONObject.fromObject(message.getPayload());
            } catch (Exception e) {
                //回复一条信息,
                if(ToolsUtil.isNotNull(usergroup)){
                    sendMessageToGroup(usergroup,appUserBo);
                }else{
                    session.sendMessage(sendJsonMsg(appUserBo));
                }
            }
            String methond = (String)map.get("methond");
        }else if("[".equals(message.getPayload().substring(0,1))){
            JSONArray jsonArray = null;
            try {
                jsonArray = JSONArray.fromObject(message.getPayload());
            } catch (Exception e) {
                //回复一条信息,
                if(ToolsUtil.isNotNull(usergroup)){
                    sendMessageToGroup(usergroup,appUserBo);
                }else{
                    session.sendMessage(sendJsonMsg(appUserBo));
                }
            }
        }else{
            //回复一条信息,
            if(ToolsUtil.isNotNull(usergroup)){
                sendMessageToGroup(usergroup,appUserBo);
            }else{
                session.sendMessage(sendJsonMsg(appUserBo));
            }
        }

    }


    /**
     * 当新连接建立的时候,被调用
     * 连接成功时候,会触发页面上onOpen方法
     * @param session session
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //已建立连接的用户
        ArrayList<WebSocketSession> users = new ArrayList<>();
        users.add(session);
        // 这块会实现自己业务,比如,当用户登录后,会把离线消息推送给用户
        String userId = (String) session.getAttributes().get("WEBSOCKET_ID");
        //已建立的用户分组
        String usergroup = (String) session.getAttributes().get("WEBSOCKET_GROUP");
        //昵称
        String nickName = (String) session.getAttributes().get("WEBSOCKET_NICK_NAME");
        if(usergroup==null){
            userMap.put("",users);
        }else{
            userMap.put(usergroup,users);
        }
        logger.info(usergroup+"组下用户:" + userId +",昵称:"+nickName+ " 连接成功");
        session.sendMessage(sendJsonMsg(session,"连接成功"));
        //session.sendMessage(sendJsonMsg(session,"欢迎萌新~"));
    }

    /**
     * 当连接关闭时被调用
     * @param session session
     * @param status 连接状态
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String username = (String) session.getAttributes().get("WEBSOCKET_ID");
        //已建立的用户分组
        String usergroup = (String) session.getAttributes().get("WEBSOCKET_GROUP");
        ArrayList<WebSocketSession> userList  = userMap.get(usergroup);
        logger.info(usergroup+"组下用户 " + username + " 连接关闭. 状态: " + status);
        userList.remove(session);
        //当该组成员为空的时候,删除该组
        if(userList.size()<=0){
            userMap.remove(usergroup);
        }
    }

    /**
     * 传输错误时调用
     * @param session session
     * @param exception 异常
     * @throws Exception 异常
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        String username = (String) session.getAttributes().get("WEBSOCKET_ID");
        if (session.isOpen()) {
            session.close();
        }
        //已建立的用户分组
        String usergroup = (String) session.getAttributes().get("WEBSOCKET_GROUP");
        ArrayList<WebSocketSession> userList  = userMap.get(usergroup);
        logger.debug(usergroup+"组下用户 " + username +" websocket 连接传输错误......");
        userList.remove(session);
    }

    /**
     * 给所有在线用户发送消息
     * @param message 发送消息
     */
    public void sendMessageToUsers(String message) {
        //遍历组map
        Set<String> set = userMap.keySet();
        for (String key:set) {
            ArrayList<WebSocketSession> users = userMap.get(key);
            //遍历组下成员
            for (WebSocketSession user : users) {
                try {
                    if (user.isOpen()) {
                        user.sendMessage(sendJsonMsg(message,null,null));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 给某个用户发送消息
     * @param userId 用户id
     * @param message 发送信息
     */
    public void sendMessageToUser(String userId,String message) {
        //遍历组map
        Set<String> set = userMap.keySet();
        for (String key:set) {
            ArrayList<WebSocketSession> users = userMap.get(key);
            //遍历组下成员
            for (WebSocketSession user : users) {
                if (user.getAttributes().get("WEBSOCKET_ID").equals(userId)) {
                    try {
                        if (user.isOpen()) {
                            user.sendMessage(sendJsonMsg(message,userId,null));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
    }

    /**
     * 给某个组下所有用户发送消息
     * @param groupName 分组
     * @param message 消息
     */
    public void sendMessageToGroup(String groupName,String message) {
        if(groupName!=null){
            //取出该分组名下的用户列表
            ArrayList<WebSocketSession> userList = userMap.get(groupName);
            if(userList!=null&&userList.size()>0){
                for(WebSocketSession user:userList){
                    if (user.isOpen()) {
                        try {
                            user.sendMessage(sendJsonMsg(message,null,groupName));
                        } catch (IOException e) {
                            logger.error("给用户"+user.getId()+"发送信息失败。");
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取当前用户id
     * @param session session
     * @return id
     */
    private String getClientId(WebSocketSession session) {
        try {
            return (String) session.getAttributes().get("WEBSOCKET_ID");
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取当前用户WebSocketSession信息
     * @param userId 用户id
     * @return 当前用户WebSocketSession信息
     */
    public WebSocketSession getUserWebSocketSession(String userId) {
        //遍历组map
        Set<String> set = userMap.keySet();
        for (String key:set) {
            ArrayList<WebSocketSession> users = userMap.get(key);
            //遍历组下成员
            for (WebSocketSession user : users) {
                if (user.getAttributes().get("WEBSOCKET_ID").equals(userId)) {
                    return user;
                }
            }
        }
        return null;
    }

    /**
     * 获取当前用户所在分组
     * @param session session
     * @return 分组名
     */
    private String getGroupName(WebSocketSession session) {
        try {
            return (String) session.getAttributes().get("WEBSOCKET_GROUP");
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取所有分组名称
     * @return 分组名称
     */
    public List<String>  getAllUserGroup() {
        //取出所有分组名称
        Set<String> set = userMap.keySet();
        //放入list内
        return new ArrayList<>(set);
    }

    /***
     * 取出该分组下用户信息
     * @param groupName 分组名称
     * @return 返回
     */
    public ArrayList<WebSocketSession> getGroupUserWebSocketSession(String groupName) {
        ArrayList<WebSocketSession> userList = new ArrayList<>(2);
        try {
            if(groupName!=null){
                 userList = userMap.get(groupName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return userList;
    }

    /**
     * 获取所有用户的信息
     * @return 所有用户的信息
     */
    public ArrayList<WebSocketSession> getAllUserWebSocket() {
        ArrayList<WebSocketSession> allUserList = new ArrayList<>();
        //遍历组map
        Set<String> set = userMap.keySet();
        for (String key:set) {
            ArrayList<WebSocketSession> users = userMap.get(key);
            //遍历组下成员
            for (WebSocketSession user : users) {
                if (user.isOpen()) {
                    allUserList.add(user);
                }
            }
        }
        return allUserList;
    }

    /**
     * 将消息转换为json格式发送
     * @param session session
     * @param msg 消息
     * @return TextMessage类型
     */
    private TextMessage sendJsonMsg(WebSocketSession session,String msg){
        String backMsg = "{}";
        //用户id
        String userId = (String) session.getAttributes().get("WEBSOCKET_ID");
        //已建立的用户分组
        String userGroup = (String) session.getAttributes().get("WEBSOCKET_GROUP");
        //昵称
        String nickName = (String) session.getAttributes().get("WEBSOCKET_NICK_NAME");
        if(ToolsUtil.isNotNull(userId)&&ToolsUtil.isNotNull(userGroup)){
            Map<String,Object> mapTmp = new HashMap<>();
            mapTmp.put("userId",userId);
            mapTmp.put("nick_name",nickName);
            mapTmp.put("userGroup",userGroup);
            mapTmp.put("msg",msg);
            //json化
            backMsg = JSONObject.fromObject(mapTmp).toString();
        }
        return new TextMessage(backMsg);
    }

    /**
     * 将消息转换为json格式发送
     * @param msg 消息
     * @param userId 用户id
     * @param userGroup 用户组
     * @return TextMessage类型消息
     */
    private TextMessage sendJsonMsg(String msg,String userId,String userGroup){
        String backMsg = null;
        Map<String,Object> mapTmp = new HashMap<>();
        if(ToolsUtil.isNotNull(userId)){
            mapTmp.put("userId",userId);
        }
        if(ToolsUtil.isNotNull(userGroup)){
            mapTmp.put("userGroup",userGroup);
        }
        mapTmp.put("msg",msg);
        //json化
        backMsg = JSONObject.fromObject(mapTmp).toString();
        return new TextMessage(backMsg);
    }

    /**
     * 将消息转换为json格式发送
     * @param appUserBo 用户消息对象
     * @return TextMessage类型消息
     */
    private TextMessage sendJsonMsg(AppUserBo appUserBo){
        String backMsg = null;
        String userId = appUserBo.getWebSocketId();
        String userGroup = appUserBo.getWebSocketIdGroup();
        String nickname = appUserBo.getNick_name();
        Map<String,Object> mapTmp = new HashMap<>();
        if(ToolsUtil.isNotNull(appUserBo)){
            mapTmp.put("userId",userId);
        }
        if(ToolsUtil.isNotNull(userGroup)){
            mapTmp.put("userGroup",userGroup);
        }
        if(ToolsUtil.isNotNull(nickname)){
            mapTmp.put("nick_name",nickname);
        }
        mapTmp.put("msg",appUserBo.getSendWebSocketMsg());
        //json化
        backMsg = JSONObject.fromObject(mapTmp).toString();
        return new TextMessage(backMsg);
    }

    /**
     * 对小组发送消息
     * @param groupName 小组名
     * @param appUserBo app用户对象
     */
    public void sendMessageToGroup(String groupName,AppUserBo appUserBo) {
        if(groupName!=null){
            //取出该分组名下的用户列表
            ArrayList<WebSocketSession> userList = userMap.get(groupName);
            if(userList!=null&&userList.size()>0){
                for(WebSocketSession user:userList){
                    if (user.isOpen()) {
                        try {
                            user.sendMessage(sendJsonMsg(appUserBo));
                        } catch (IOException e) {
                            logger.error("给用户"+user.getId()+"发送信息失败。");
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * 给所有在线用户发送消息
     * @param appUserBo app用户对象
     */
    public void sendMessageToUsers(AppUserBo appUserBo) {
        //遍历组map
        Set<String> set = userMap.keySet();
        for (String key:set) {
            ArrayList<WebSocketSession> users = userMap.get(key);
            //遍历组下成员
            for (WebSocketSession user : users) {
                try {
                    if (user.isOpen()) {
                        user.sendMessage(sendJsonMsg(appUserBo));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 给某个用户发送消息
     * @param userId 用户id
     * @param appUserBo app用户对象
     */
    public void sendMessageToUser(String userId,AppUserBo appUserBo) {
        //遍历组map
        Set<String> set = userMap.keySet();
        for (String key:set) {
            ArrayList<WebSocketSession> users = userMap.get(key);
            //遍历组下成员
            for (WebSocketSession user : users) {
                if (user.getAttributes().get("WEBSOCKET_ID").equals(userId)) {
                    try {
                        if (user.isOpen()) {
                            user.sendMessage(sendJsonMsg(appUserBo));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                }
            }
        }
    }
}

java后台发送信息

当前台通过ws进行连接后,就可以使用ajax调用后台写的代码了,这个就比较随意了…

	@Autowired
    WebSocketHandler infoHandler;

    @RequestMapping("/test.json")
    public void login(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取用户id
        String userId = (String)request.getSession().getAttribute("SESSION_ID");
        //用户分组
        String usergroup = (String)request.getSession().getAttribute("SESSION_GROUP");
        String msg = request.getParameter("msg");
        String group = request.getParameter("group");
        if(group!=null&&!("".equals(group.trim()))){
            if(msg!=null&&!("".equals(msg.trim()))){
                infoHandler.sendMessageToGroup(new TextMessage(usergroup+"组"+userId+"发言:"+msg),group);
            }
        }else{
            if(msg!=null&&!("".equals(msg.trim()))){
                infoHandler.sendMessageToUsers(new TextMessage(usergroup+"组"+userId+"发言:"+msg));
            }
        }

    }
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Spring Boot框架整合WebSocket实现在线客服的聊天功能的实现原理如下: 1. 在Spring Boot项目中引入WebSocket依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建WebSocket配置类,并添加@EnableWebSocket注解: ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/chat").setAllowedOrigins("*"); } @Bean public WebSocketHandler myHandler() { return new MyHandler(); } } ``` 3. 创建WebSocket处理器,实现WebSocketHandler接口: ```java public class MyHandler implements WebSocketHandler { private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); } @Override public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { for (WebSocketSession s : sessions) { if (s.isOpen() && !s.getId().equals(session.getId())) { s.sendMessage(message); } } } @Override public void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception { // do nothing } @Override public void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception { // do nothing } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { session.close(CloseStatus.SERVER_ERROR); sessions.remove(session); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { sessions.remove(session); } @Override public boolean supportsPartialMessages() { return false; } } ``` 4. 在前端页面中使用JavaScript创建WebSocket连接,并发送消息: ```javascript var socket = new WebSocket("ws://localhost:8080/chat"); socket.onopen = function() { console.log("WebSocket连接已打开"); }; socket.onmessage = function(event) { console.log("收到消息:" + event.data); }; socket.onclose = function(event) { console.log("WebSocket连接已关闭"); }; socket.onerror = function(event) { console.log("WebSocket连接发生错误"); }; function sendMsg() { var msg = document.getElementById("msg").value; socket.send(msg); } ``` 通过以上步骤,就可以实现基于Spring Boot框架的在线客服聊天功能了。用户在前端页面中发送消息,后台通过WebSocket处理器接收并转发消息给其他在线用户。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值