Springboot集成WebSocket

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

相关文章
相关标签/搜索