Java实现websocket的连接以及简易聊天室的后台服务实现
websocket可以类似长连接,建立好session连接后,可以实现服务端主动推送信息到客户端服务。
http连接是客户端发请求服务端返回数据,websocket可以实现服务端多次向客户端发送数据包。
pom.xml文件配置在基于`org.springframework.boot`:
<!-- websocket包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
配置WebSocketConfig中:
@Configuration
public class WebSocketConfig {
/**
* 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解声明的 websocket endpoint
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
webSocket服务实现:
@ServerEndpoint(value = "/imServer/{username}") //类似于Controller中的路径
@Component
public class WebSocketServer {
private static final Logger logs = LoggerFactory.getLogger(WebSocketServer.class);
public static final Map<String,Session> sessionMap = new ConcurrentHashMap<>();
/**
* 创建链接
* @param session
*/
@OnOpen
public void onOpen(Session session, @PathParam("username") String username){
sessionMap.put(username,session);
logs.info("新用户加入username:{},当前人数:{}",username,sessionMap.size());
JSONObject result = new JSONObject();
JSONArray array = new JSONArray();
result.put("users",array);
for(Object key :sessionMap.keySet()){
JSONObject jsonObject = new JSONObject();
jsonObject.put("username",key);
array.add(jsonObject);
}
sedAllMessage(JSONUtils.toJSONString(result));//把当前用户列表返给客户端
}
/**
* 关闭连接
* @param session
* @param username 指定关闭哪一个session连接
*/
@OnClose
public void onClose(Session session, @PathParam("username") String username){
sessionMap.remove(username);
logs.info(username+"连接关闭成功");
}
/**
* 消息中转站
* 接收到客户端消息后调用此方法
* @param message 客户端发来的消息
* @param username 用户名
*/
@OnMessage
public void onMessage(String message, @PathParam("username") String username){
logs.info("服务端收到用户{}的消息:{}",username,message);
JSONObject parse = (JSONObject) JSONUtils.parse(message);
String toUserName = parse.getString("to"); // 要发给谁
String text = parse.getString("text"); // 发什么信息
Session toSession = sessionMap.get(toUserName); // 找到对应用户的Session
if(toSession != null){
JSONObject json = new JSONObject();
json.put("from",username);
json.put("text",text);
this.sendMessage(toSession,json.toJSONString());
logs.info("发送到用户:{},消息:{}",toUserName,json.toJSONString());
}else {
logs.info("发送失败,未找到用户:{}的session连接",toUserName);
}
}
@OnError
public void onError(Throwable error){
logs.error("webSocket 服务异常"+error.getMessage());
error.printStackTrace();
}
/**
* 把消息发给所有客户端
* @param message
*/
private void sedAllMessage(String message){
try {
for(Session session:sessionMap.values()){
logs.info("服务端给客户端[{}]发送信息{}",session.getId(),message);
session.getBasicRemote().sendText(message);
}
} catch (IOException e) {
logs.error("服务端发送消息到客户端失败",e);
}
}
/**
* 向指定用户的session连接中发送消息
* @param session 指定用户的session
* @param message 消息文本
*/
private void sendMessage(Session session,String message){
try {
session.getBasicRemote().sendText(message);//向客户端发送信息
} catch (IOException e) {
logs.error("服务端发送消息到客户端失败",e);
}
}
}
如果用到了SpringSecurity,则需要把服务路径添加到认证范围内。SecurityConfig

HTML页面js配置
webSocketInit(){
if(typeof(WebSocket) == 'undefined'){
console.log("您当前浏览器不支持websocket")
return
}
//开启一个webSocket服务
let ws = new WebSocket('ws://localhost:8082/imServer/aa')
ws.onopen = function(){
console.log("websocket服务建立连接")
//ws.send('前端消息') // 发送信息
};
//onmessage 浏览器收消息,获得从服务端发来的文本消息
ws.onmessage = function(event){
console.log("接收到后端消息:"+event.data);
}
// 关闭
ws.onclose = function(){
console.log("websocket关闭连接")
}
//异常
ws.onerror = function(event){
console.log("异常信息"+event.data);
}
}
2841

被折叠的 条评论
为什么被折叠?



