WebSocket是一种网络通讯协议,熟悉计算机网络的人都知道,通常咱们采用的http请求,都是请求/响应的模式,即客户端发起请求,服务端从而对客户端的请求作出相应的响应,然而服务端通常都不能主动的往客户端发消息,WebSocket正好解决这一问题,本文采用springboot集成WebSocket;web
(1)在pom.xml中加入依赖:spring
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
复制代码
(2)建立一个WebSocketConfig类,在其中写入后端
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
复制代码
(3)建立一个SocketServer类,在其中写入:springboot
@ServerEndpoint(value = "/socketServer/{productId}/{mapId}")
@Component
@Slf4j
public class SocketServer {
private static final String ADMIN_USER = "server-admin";
private Session session;
private static Map<String,Session> sessionPool = new HashMap<String,Session>();
private static Map<String,String> sessionIds = new HashMap<String,String>();
private MonitorService monitorService;
private DeviceService deviceService;
private String handshake;
private String getMapId;
public static String productCopyId;
public static String mapCopyId;
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext context){
applicationContext = context;
}
/**
* 用户链接时触发
* @param productId productId
* @param mapId mapId
* @param session session
*/
@OnOpen
public void open(Session session, @PathParam(value="productId")String productId, @PathParam(value="mapId")String mapId)throws Exception{
log.info("{{}}握手成功{{}}",productId,mapId);
this.session = session;
handshake = productId;
getMapId = mapId;
productCopyId = productId;
mapCopyId = mapId;
sessionPool.put(productId, session);
sessionIds.put(session.getId(), productId);
sendMessage(handshake,handshake);
}
/**
* 收到信息时触发
* @param message message
*/
@OnMessage
public void onMessage(String message){
log.info("发送人:"+sessionIds.get(session.getId())+"内容:"+message);
}
/**
* 链接关闭触发
*/
@OnClose
public void onClose(){
sessionPool.remove(sessionIds.get(session.getId()));
sessionIds.remove(session.getId());
}
/**
* 发生错误时触发
* @param session session
* @param error error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
*信息发送的方法
* @param message message
* @param clientId clientId
*/
public synchronized static void sendMessage(String message,String clientId) throws Exception{
log.info("sendMessage方法被调用");
Session s = sessionPool.get(clientId);
if(s!=null){
try {
log.info("{{}}sendMessage发送的消息为{{}}",clientId ,message);
s.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 获取当前链接数
* @return int
*/
public synchronized static int getOnlineNum(){
if(sessionIds.values().contains(ADMIN_USER)) {
return sessionPool.size()-1;
}
return sessionPool.size();
}
/**
* 获取在线用户名以逗号隔开
* @return String
*/
public synchronized static String getOnlineUsers(){
StringBuffer clientIds = new StringBuffer();
for (String key : sessionIds.keySet()) {
if (!ADMIN_USER.equals(sessionIds.get(key)))
{
clientIds.append(sessionIds.get(key)+",");
}
}
return clientIds.toString();
}
/**
* 信息群发
* @param msg
*/
public synchronized static void sendAll(String msg) throws Exception{
for (String key : sessionIds.keySet()) {
if (!ADMIN_USER.equals(sessionIds.get(key)))
{
sendMessage(msg, sessionIds.get(key));
}
}
}
/**
* 多我的发送给指定的几个用户
* @param msg
* @param clientIds 用户
*/
public synchronized static void SendMany(String msg,String [] clientIds) throws Exception{
log.info("SendMany方法被调用");
for (String clientId : clientIds) {
sendMessage(msg, clientId);
}
}
}
复制代码
至此,后端的工做基本完成了;websocket
推广一下,若是在springboot中的SocketServer类想要加载Service类,它是加载不到的,因此须要在该类中加入如下代码:网络
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext context){
applicationContext = context;
}
复制代码
用以加载springboot中的Bean类;session
而后用如下代码加载该Beanapp
deviceService = applicationContext.getBean(DeviceService.class);
复制代码
最后,须要在启动类中加入如下代码,才能加载到Beansocket
ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
复制代码
其中DemoApplication为启动类的类名,至此就能够了;(备注:若是本文侵权,请联系做者删除)spring-boot