您的位置:首页 > 编程语言 > Java开发

WebSocket使用:整合Spring实现消息推送

2018-01-30 20:59 841 查看
1 添加依赖:

<!-- WebSocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>


2 创建WebSocketHandler,用于处理WebSocket连接请求:

public class MessageHandler implements WebSocketHandler{

private static final Map<String, WebSocketSession> users;//标识用户连接

private static final String USER_KEY = "current_user";

static {
users = new ConcurrentHashMap<String,WebSocketSession>();
}

//关闭websocket连接时调用
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
String userId = getUserId(session);
if(userId != null) {
users.remove(userId);
}
}

//建立websocket连接时调用
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String userId = getUserId(session);
if(userId != null) {
users.put(userId, session);
session.sendMessage(new TextMessage("建立Socket连接成功!"));
}
}

//客户端调用websocket.send时候,会调用该方法
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
WebSocketMessage message2  = new TextMessage("服务端接收到了您的消息:"+message);
session.sendMessage(message2);
}

//传输异常时
@Override
public void handleTransportError(WebSocketSession arg0, Throwable arg1) throws Exception {

}

@Override
public boolean supportsPartialMessages() {
return false;
}

//发送消息给特定用户
public void sendMessageToUser(String userId,String contents) {
WebSocketSession session = users.get(userId);
TextMessage message = new TextMessage(contents);
if(session !=null && session.isOpen()) {
try {
session.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}

//发送消息给所有用户
public void sendMessageToAllUsers(String contents) {
Set<String> userIds = users.keySet();
for(String userId: userIds) {
this.sendMessageToUser(userId, contents);
}
}

private String getUserId(WebSocketSession session) {
try {
String userId = (String)session.
getAttributes().get(USER_KEY);
return userId;
}catch(Exception e) {
e.printStackTrace();
}
return null;
}
}


3 添加HttpSessionHandshakeInterceptor,执行WebSocketHandler前拦截:

public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {

private static final String USER_KEY = "current_user";

@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Exception e) {
super.afterHandshake(request, response, handler, e);
}

@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
Map<String, Object> attrs) throws Exception {

if(request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)request;
//获取参数
String user = serverHttpRequest .getServletRequest().getParameter("user");
//System.out.println("获取到的User:"+user);
attrs.put(USER_KEY, user);
}
return true;
}

}


4 配置WebSocket:

方式一:xml配置

<!-- websocket处理类 -->
<bean id="myHandler" class="websocket.handler.MessageHandler"/>

<!-- 握手接口/拦截器 -->
<bean id="myInterceptor" class="websocket.interceptor.WebSocketInterceptor"/>

<websocket:handlers >
<websocket:mapping path="/myHandler" handler="myHandler"/>
<websocket:handshake-interceptors>
<ref bean="myInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>

<!--  注册 sockJS -->
<websocket:handlers>
<websocket:mapping path="/sockjs/myHandler" handler="myHandler"/>
<websocket:handshake-interceptors>
<ref bean="myInterceptor"/>
</websocket:handshake-interceptors>
<websocket:sockjs />
</websocket:handlers>


方法二:java代码

package websocket.config;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer{

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myHandler(),"/myHandler" ).
addInterceptors(new WebSocketInterceptor());
registry.addHandler(myHandler(),"/sockjs/myHandler" ).
addInterceptors(new WebSocketInterceptor()).withSockJS();
}

@Bean
public WebSocketHandler myHandler() {
return new MessageHandler();
}
}


同时,spring配置文件添加:

<context:component-scan base-package="websocket.config"/>


5 服务端主动发送消息给客户端:

@Autowired
private MessageHandler messageHandler;

/*
//发送消息给特定用户
messageHandler.sendMessageToUser("xxxx");
//改善消息给所有用户
messageHandler.sendMessageToAllUsers("xxxxx");
*/


6 前端代码:传递带userid参数请求

var websocket;

// 首先判断是否 支持 WebSocket
if('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/WebSocket-Start/myHandler?user=minghai");
} else if('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://localhost:8080/WebSocket-Start/myHandler?user=minghai");
} else {
websocket = new SockJS("http://localhost:8080/WebSocket-Start/sockjs/myHandler?user=minghai");
}

// 打开连接时
websocket.onopen = function(evnt) {
console.log("  websocket.onopen  ");
};

// 收到消息时
websocket.onmessage = function(evnt) {
alert(evnt.data);
};

websocket.onerror = function(evnt) {
console.log("  websocket.onerror  ");
};

websocket.onclose = function(evnt) {
console.log("  websocket.onclose  ");
};

//客户端主动发消息
websocket.send("");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  websocket