1.WebSocketConfig
package com.qcby.teach.help.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author lw
* @date 2021年07月16日 14:46
*/
@Configuration
public class WebSocketConfig {
/**
* 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
2.WebSocketEndpoint(用于接收和发送数据)
package com.qcby.teach.help.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.boot.autoconfigure.session.SessionProperties;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author lw
* @date 2021年07月16日 14:48
*/
@Slf4j
//ws:localhost:8080//websocket/{account}
@ServerEndpoint(value = "/websocket/{account}")
//@Component
public class WebSocketEndpoint {
/** 记录当前在线连接数 */
private static AtomicInteger onlineCount = new AtomicInteger(0);
// 与客户端的链接回话,需要用他来发送数据
private Session session;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @Param("account") String account) {
onlineCount.incrementAndGet(); // 在线数加1
log.info("有新连接加入:{},当前在线人数为:{}", session.getId(), onlineCount.get());
SessionPool.sessions.put(account,session);//加入用户到连接池中
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) throws IOException {
onlineCount.decrementAndGet(); // 在线数减1
log.info("有一连接关闭:{},当前在线人数为:{}", session.getId(), onlineCount.get());
SessionPool.close(session.getId());//从链接池中删除用户信息
session.close();//关闭当前链接
}
/**
* 收到客户端消息后调用的方法
*
* @param message
* 客户端发送过来的消息
*/
@OnMessage
public void onMessage(@Param("message") String message, Session session) {
log.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
this.sendMessage("Hello, " + message, session);
}
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 服务端发送消息给客户端
*/
private void sendMessage(String message, Session toSession) {
try {
log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
toSession.getBasicRemote().sendText(message);
} catch (Exception e) {
log.error("服务端发送消息给客户端失败:{}", e);
}
}
}
3.SpringPool(用于配置从链接池中获取和删除数据)
package com.qcby.teach.help.config;
import javax.websocket.Session;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author lw
* @date 2021年07月16日 14:58
*/
public class SessionPool {
/** 存放所有在线的客户端 */
public static Map<String, Session> sessions = new ConcurrentHashMap<>();
public static void close(String sessionId) throws IOException {
Session session=sessions.get(sessionId);//获取当前hashmap中的key值
if(session!=null){
sessions.get(sessionId).close();//如果当前池中有key对应的value值,则进行清除操作
}
}
public static void sendMessage(String sessionId,String message){//一对一发送,用于学生回复老师是否听懂
sessions.get(sessionId).getAsyncRemote().sendText(message);//获取需要发送的用户,并发送信息
}
public static void sendMessage(String message){//对当前所有的链接进行发送,用于老师向学生提问是否听懂
for(String sessionId:SessionPool.sessions.keySet())
{
sessions.get(sessionId).getAsyncRemote().sendText(message);//获取需要发送的用户,并发送信息
}
}
}
|