App将做微信小程序的版本了,由于用到了TCP推送,所以需要用websocket实现一遍。利用spring 的websocket来实现还是很简单的。这里有一个非常大的坑,由于我这个是纯只做websocket连接的,想开始将spring mvc给去掉。确怎么也连不上,这里还是需要对websocket的原理知晓一些。它是先走http再走tcp的。所以spring mvc必须要!
spring mvc不在这里讨论。请看socket部分。
bom.xml
<!-- spring 相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.mvc}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${org.springframework.version}</version>
</dependency>
spring websocket的核心在于注册。
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{
@Autowired
WebSocketHandler webSocketHandler;
@Autowired
HandshakeInterceptor handshakeInterceptor;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
//允许连接的域,只能以http或https开头 必须设置哦,不然会出现403的错误 failed: Error during WebSocket handshake: Unexpected response code: 403
// String[] allowsOrigins = {"http://www.xxx.com"};
String[] allowsOrigins = {"*"};
registry.addHandler(webSocketHandler,"/appwebsocket").addInterceptors(handshakeInterceptor).setAllowedOrigins(allowsOrigins); //支持websocket 的访问链接
registry.addHandler(webSocketHandler,"/sockjs/appwebsocket").addInterceptors(handshakeInterceptor).setAllowedOrigins(allowsOrigins).withSockJS(); //不支持websocket的访问链接
}
}
然后是 handshakeInterceptor, 这个是握手时需要做的事情。
@Component
public class HandshakeInterceptor implements org.springframework.web.socket.server.HandshakeInterceptor{
/**
* 初次握手访问前
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
return true;
}
/**
* 初次握手访问后
*/
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception exception) {
}
}
然后是WebSocketHandler,这个是所有请求的处理类。
@Component
@Scope("prototype")
public class WebSocketHandler implements org.springframework.web.socket.WebSocketHandler{
private static final Logger log = LoggerFactory.getLogger(WebSocketHandler.class);
@Autowired
Config config;
@Autowired
AllConnections allConnections;
@Autowired
PushCommandClient pushCommandClient;
/**
* 初次连接成功
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
allConnections.putClientAppIoSession(session);
log.info("连接成功。。。添加到链接管理,添加完后当前拥有链接数为:"+allConnections.getAppConnectionSize());
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> socketmessage) throws Exception {
if (log.isInfoEnabled()) {
log.info("app连接:触发handleMessage读取app信息");
}
if(socketmessage.getPayloadLength()==0){
log.info("收到websocket包,包内容为空!!!");
return;
}
JSONObject object = JSON.parseObject(socketmessage.getPayload().toString());
//收到json数据,需要处理。。。
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
log.error("链接出错,关闭链接......",exception);
if(session.isOpen()){
session.close();
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
if (log.isInfoEnabled()) {
log.info("app连接:触发afterConnectionClosed移除缓存的连接,移除前连接数为:"+allConnections.getAppConnectionSize());
}
allConnections.removeClientAppIoSession(session);
if (log.isInfoEnabled()) {
log.info("app连接关闭.channel ID 为:"+session.getId()+" ip:"+session.getRemoteAddress()+",当前剩余设备连接数为:"+allConnections.getAppConnectionSize());
}
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
最后附上一个测试用的客户端代码!
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- 可选的Bootstrap主题文件(一般不用引入) -->
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!--<script type="text/javascript" src="js/jquery-1.7.2.js"></script>-->
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<title>webSocket测试</title>
<script type="text/javascript">
$(function(){
var websocket;
if ('WebSocket' in window) {
alert("WebSocket");
websocket = new WebSocket("ws://ip:10000/webtcpnode/appwebsocket");
} else if ('MozWebSocket' in window) {
alert("MozWebSocket");
websocket = new MozWebSocket("ws://webtcpnode/appwebsocket");
} else {
alert("SockJS");
websocket = new SockJS("http://127.0.0.1/webtcpnode/sockjs/appwebsocket/");
}
websocket.onopen = function (evnt) {
$("#tou").html("链接服务器成功!")
};
websocket.onmessage = function (evnt) {
$("#msg").html($("#msg").html() + "<br/>" + evnt.data);
};
websocket.onerror = function (evnt) {
};
websocket.onclose = function (evnt) {
$("#tou").html("与服务器断开了链接!")
}
$('#send').bind('click', function() {
send();
});
function send(){
if (websocket != null) {
var message = document.getElementById('message').value;
websocket.send(message);
} else {
alert('未与服务器链接.');
}
}
});
</script>
</head>
<body>
<div class="page-header" id="tou">
webSocket及时聊天Demo程序
</div>
<div class="well" id="msg">
</div>
<div class="col-lg">
<div class="input-group">
<input type="text" class="form-control" placeholder="发送信息..." id="message">
<span class="input-group-btn">
<button class="btn btn-default" type="button" id="send" >发送</button>
</span>
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div><!-- /.row -->
</body>
</html>