SpringBoot-WebSocket 聊天室

配置类Config

// websocket配置
@Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

业务类Controller

import org.springframework.stereotype.Component;
 
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
 
/**
 *  * @Description: websocket的具体实现类
 *  * 使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,
 *  * 但在springboot中连容器都是spring管理的。
 *     虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean
 *     所以可以用一个静态set保存起来。
*/
@ServerEndpoint(value = "/websocket/{nickName}")
@Component
public class MyWebSocket {
    //用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
    private static Map<Session, UserInfo> connectmap = new HashMap<>();//用session作为key,保存用户信息
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("nickName") String nickName) {
        this.session = session;
        UserInfo userInfo = new UserInfo(session.getId(),nickName);
        connectmap.put(session,userInfo);
        webSocketSet.add(this);     //加入set中
        System.out.println(nickName+" 上线了!当前在线人数为" + webSocketSet.size());
        //群发消息,告诉每一位
        broadcast(nickName+" 上线了!-->当前在线人数为:"+webSocketSet.size());
    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        String nickName=connectmap.get(session).getNickName();
        connectmap.remove(session);
        webSocketSet.remove(this);  //从set中删除
        System.out.println(nickName+" 下线了!当前在线人数为" + webSocketSet.size());
        //群发消息,告诉每一位
        broadcast(nickName+" 下线,当前在线人数为:"+webSocketSet.size());
    }
    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     * */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("来自客户端的消息:" + message);
        //群发消息
        String nickName=connectmap.get(session).getNickName();
        broadcast(nickName+" 说:"+message);
    }
    /**
     * 发生错误时调用
     *
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }
    /**
     * 群发自定义消息
     * */
    public  void broadcast(String message){
        for (MyWebSocket item : webSocketSet) {
            //同步异步说明参考:http://blog.csdn.net/who_is_xiaoming/article/details/53287691
            //this.session.getBasicRemote().sendText(message);
            item.session.getAsyncRemote().sendText(message);//异步发送消息.
        }
    }
}

实体类Entity

public class UserInfo {
    private String id;
    private String nickName;
    private String password;
 
    public UserInfo() {
    }
 
    public UserInfo(String id, String nickName) {
        this.id = id;
        this.nickName = nickName;
    }
 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    public String getNickName() {
        return nickName;
    }
 
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
}

About ME

👋 读书城南,🤔 在未来面前,我们都是孩子~
  • 📙 一个热衷于探索学习新方向、新事物的智能产品经理,闲暇时间喜欢coding💻、画图🎨、音乐🎵、学习ing~
👋 Social Media
👋 加入小组~

👋 感谢打赏~