更新websocket,非Stomp协议的原生WebSocket协议。
This commit is contained in:
parent
03cb51fd4a
commit
4b56e79eac
@ -0,0 +1,45 @@
|
||||
package com.xncoding.jwt.commons;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* JacksonUtil
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/3/4
|
||||
*/
|
||||
public class JacksonUtil {
|
||||
private static ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public static String bean2Json(Object obj) {
|
||||
try {
|
||||
return mapper.writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
|
||||
// try {
|
||||
// return mapper.readValue(jsonStr, objClass);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
public static <T> T json2Bean(String jsonStr, TypeReference<T> typeReference) {
|
||||
try {
|
||||
return mapper.readValue(jsonStr, typeReference);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +1,25 @@
|
||||
package com.xncoding.jwt.config;
|
||||
|
||||
import com.xncoding.jwt.handler.SocketHandler;
|
||||
import com.xncoding.jwt.interceptor.WebSocketInterceptor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
|
||||
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
|
||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||
|
||||
/**
|
||||
* WebSocketConfig
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/2/28
|
||||
* @since 2018/3/22
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
|
||||
stompEndpointRegistry.addEndpoint("/simple")
|
||||
.setAllowedOrigins("*") //解决跨域问题
|
||||
.withSockJS();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.enableSimpleBroker("/topic");
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(new SocketHandler(), "/app")
|
||||
.addInterceptors(new WebSocketInterceptor())
|
||||
.setAllowedOrigins("*");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
package com.xncoding.jwt.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
|
||||
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
|
||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||
|
||||
/**
|
||||
* STOMP协议的WebStocket
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/2/28
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketStompConfig extends AbstractWebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
|
||||
stompEndpointRegistry.addEndpoint("/simple")
|
||||
.setAllowedOrigins("*") //解决跨域问题
|
||||
.withSockJS();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.enableSimpleBroker("/topic");
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package com.xncoding.jwt.handler;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.xncoding.jwt.commons.JacksonUtil;
|
||||
import com.xncoding.jwt.model.WsParam;
|
||||
import com.xncoding.jwt.model.WsResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* SocketHandler
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/3/22
|
||||
*/
|
||||
@Component
|
||||
public class SocketHandler extends TextWebSocketHandler {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
|
||||
|
||||
@Override
|
||||
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
|
||||
logger.info("handleTextMessage start");
|
||||
// 将消息进行转化,因为是消息是json数据,可能里面包含了发送给某个人的信息,所以需要用json相关的工具类处理之后再封装成TextMessage,
|
||||
// 我这儿并没有做处理,消息的封装格式一般有{from:xxxx,to:xxxxx,msg:xxxxx},来自哪里,发送给谁,什么消息等等
|
||||
String msg = message.getPayload();
|
||||
logger.info("msg = " + msg);
|
||||
WsParam wsParam = JacksonUtil.json2Bean(msg, new TypeReference<WsParam>(){});
|
||||
if ("list".equals(wsParam.getMethod())) {
|
||||
logger.info("call list method...");
|
||||
WsResponse response = new WsResponse();
|
||||
response.setResult("hello list");
|
||||
sendMessageToUser(session, new TextMessage(JacksonUtil.bean2Json(response)));
|
||||
}
|
||||
logger.info("handleTextMessage end");
|
||||
// 给所有用户群发消息
|
||||
//sendMessagesToUsers(msg);
|
||||
// 给指定用户群发消息
|
||||
//sendMessageToUser(userId, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
logger.info("Connected ... " + session.getId());
|
||||
sessions.add(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||
if (session.isOpen()) {
|
||||
session.close();
|
||||
}
|
||||
sessions.remove(session);
|
||||
logger.info(String.format("Session %s closed because of %s", session.getId(), status.getReason()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable throwable) throws Exception {
|
||||
logger.error("error occured at sender " + session, throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给所有的用户发送消息
|
||||
*/
|
||||
public void sendMessagesToUsers(TextMessage message) {
|
||||
for (WebSocketSession user : sessions) {
|
||||
try {
|
||||
// isOpen()在线就发送
|
||||
if (user.isOpen()) {
|
||||
user.sendMessage(message);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息给指定的用户
|
||||
*/
|
||||
private void sendMessageToUser(WebSocketSession user, TextMessage message) {
|
||||
try {
|
||||
// 在线就发送
|
||||
if (user.isOpen()) {
|
||||
user.sendMessage(message);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("发送消息给指定的用户出错", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.xncoding.jwt.interceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* WebSocketInterceptor
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/3/22
|
||||
*/
|
||||
public class WebSocketInterceptor implements HandshakeInterceptor {
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@Override
|
||||
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse arg1,
|
||||
WebSocketHandler arg2, Map<String, Object> arg3) throws Exception {
|
||||
// 将ServerHttpRequest转换成request请求相关的类,用来获取request域中的用户信息
|
||||
if (request instanceof ServletServerHttpRequest) {
|
||||
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
|
||||
HttpServletRequest httpRequest = servletRequest.getServletRequest();
|
||||
}
|
||||
logger.info("beforeHandshake完成");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterHandshake(ServerHttpRequest arg0, ServerHttpResponse arg1, WebSocketHandler arg2, Exception arg3) {
|
||||
logger.info("afterHandshake完成");
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.xncoding.jwt.model;
|
||||
|
||||
/**
|
||||
* WsParam
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/3/22
|
||||
*/
|
||||
public class WsParam {
|
||||
private String method;
|
||||
private Object param;
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public Object getParam() {
|
||||
return param;
|
||||
}
|
||||
|
||||
public void setParam(Object param) {
|
||||
this.param = param;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.xncoding.jwt.model;
|
||||
|
||||
/**
|
||||
* WsResponse
|
||||
*
|
||||
* @author XiongNeng
|
||||
* @version 1.0
|
||||
* @since 2018/3/22
|
||||
*/
|
||||
public class WsResponse {
|
||||
private Object result;
|
||||
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>广播式WebSocket</title>
|
||||
<script src="js/sockjs.min.js"></script>
|
||||
<script src="js/stomp.js"></script>
|
||||
<script src="js/jquery-3.1.1.js"></script>
|
||||
</head>
|
||||
<body onload="disconnect()">
|
||||
<noscript><h2 style="color: #e80b0a;">Sorry,浏览器不支持WebSocket</h2></noscript>
|
||||
<div>
|
||||
<div>
|
||||
<button id="connect" onclick="connect();">连接</button>
|
||||
<button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>
|
||||
</div>
|
||||
|
||||
<div id="conversationDiv">
|
||||
<label>输入你的名字</label><input type="text" id="name"/>
|
||||
<button id="sendName" onclick="sendName();">发送</button>
|
||||
<p id="response"></p>
|
||||
<p id="callback"></p>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var ws;
|
||||
function connect() {
|
||||
ws = new WebSocket('ws://localhost:8092/app');
|
||||
ws.onmessage = function(data){
|
||||
console.log("msg = " + JSON.stringify(data.data));
|
||||
showResponse(data.data);
|
||||
};
|
||||
setConnected(true);
|
||||
}
|
||||
|
||||
function disconnect() {
|
||||
if (ws != null) {
|
||||
ws.close();
|
||||
}
|
||||
setConnected(false);
|
||||
console.log("Disconnected");
|
||||
}
|
||||
|
||||
function sendName() {
|
||||
var data = {
|
||||
"method": "list",
|
||||
"param": $("#name").val()
|
||||
};
|
||||
ws.send(JSON.stringify(data));
|
||||
}
|
||||
|
||||
function showResponse(message) {
|
||||
$("#response").html(message);
|
||||
}
|
||||
function showCallback(message) {
|
||||
$("#callback").html(message);
|
||||
}
|
||||
function setConnected(connected) {
|
||||
document.getElementById("connect").disabled = connected;
|
||||
document.getElementById("disconnect").disabled = !connected;
|
||||
document.getElementById("conversationDiv").style.visibility = connected ? 'visible' : 'hidden';
|
||||
$("#response").html();
|
||||
$("#callback").html();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user