前端:
export default{
websoket: null,
init:function(url){
let _this = this;
this.websoket = new WebSocket(url);
this.websoket.onopen = function(event){//成功创建连接
_this.onOpen(event);
};
this.websoket.onerror = function(event){//连接出现错误
_this.onError(event);
};
this.websoket.onmessage = function(event){//收到服务器发送的信息
_this.onMessage(event);
};
this.websoket.onclose = function(event){//关闭websocket
_this.onClose(event);
};
},
onOpen:function(event){
console.log("建立连接");
this.websoket.send("前端发送信息到后端");
},
onError:function(event){
console.log("发生错误");
},
onMessage:function(event){
console.log("服务器端发送信息至前端");
},
onClose:function(event){
console.log("服务器端要求关闭websoket");
}
}
服务器配置:有2种配置方式:注解模式(推荐方式)、XML配置
注解模式:
WebSocketConfig:配置类
package sino.com.websoket;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
/**
注:该类需要放在SpringMVC扫描路径下
@Configuration//指明该类为Spring配置类
@EnableWebSocket//声明该类支持websocket
*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer{、
@Resource TopoTreeHandler topoTreeHandler;
@Resource TopoTreeInterceptor topoTreeInterceptor;
/**
支持websocket 的访问链接
setAllowedOrigins:允许跨域
*/
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(topoTreeHandler, "/testWebSoket.ws").addInterceptors(topoTreeInterceptor).setAllowedOrigins("*");
}
}
XML配置模式:spring.xml配置文件中
<websocket:handlers allowed-origins="*">
<websocket:mapping path="/testWebSoket.ws" handler="topoTreeHandler"/>
<websocket:handshake-interceptors>
<bean class="sino.com.websoket.TopoTreeInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>
TopoTreeInterceptor:拦截器
package sino.com.websoket;
import java.util.Date;
import java.util.Map;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
/**
* Socket建立连接(握手)和断开
* @author ZDB
*
*/
@Component
public class TopoTreeInterceptor implements HandshakeInterceptor{
@Override
public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler esHandler,
Map<String, Object> map) throws Exception {
return true;
}
@Override
public void afterHandshake(ServerHttpRequest arg0, ServerHttpResponse arg1, WebSocketHandler arg2, Exception arg3) {
// TODO Auto-generated method stub
}
}
TopoTreeHandler:
package sino.com.websoket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
@Component
@RequestMapping("/testWebSoket.ws")
public class TopoTreeHandler implements WebSocketHandler {
public TopoTreeHandler() {
System.out.println("初始化TopoTreeHandler对象");
}
//存储当前所有的在线用户socket
//目前以userId为key,所以一个用户打开多个socket页面时只会在最新的页面推送消息
private static final List<WebSocketSession> sessionMap = new ArrayList<>();
//socket 连接常见时该方法被调用
@Override
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
//在socket Interceptor中设置的参数、
System.out.println("完成创建链接");
sessionMap.add(webSocketSession);
TopoTreeHandler.sendMessage(new TextMessage(new Date() + ""));
}
@Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> message) throws Exception {
System.out.println("前端发送的消息="+message.toString());
}
//连接出错时
@Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable e) throws Exception {
System.out.println("创建链接出错");
if (webSocketSession.isOpen()) {
webSocketSession.close();
}
sessionMap.remove(webSocketSession);
}
//连接关闭时
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
System.out.println("关闭链接");
}
@Override
public boolean supportsPartialMessages() {
// TODO Auto-generated method stub
return false;
}
//向某个用户发送消息
public void sendMessage(TextMessage message, String userId) {
// WebSocketSession user = users.get(userId);
// if (null != user && user.isOpen()) {
// try {
// user.sendMessage(message);
// } catch (Exception e) {
// }
// }
}
//批量向所有用户发送消息
public static void sendMessage(TextMessage message) {
for (WebSocketSession session : sessionMap) {
System.out.println("session="+session);
if (session.isOpen()) {
try {
session.sendMessage(message);
} catch (Exception e) {
}
}
}
}
}
网友评论