Spring+WebSocket+SockJSリアルタイムチャットを実現
設計の初心はwebsocketを通じてホームページのリアルタイム通信チャットを実現することである.
エンジニアリング環境:tomcat 8+jdk 1.7+maven+eclipse
設計構想:クライアントがホームページにログインしてsocket接続を確立し、バックグラウンドにユーザー接続情報を記録し、標識を行う.ユーザがウェブページ側でチャットメッセージをバックグラウンドに送信すると、バックグラウンドは情報を受信した後、メッセージを受信者に送信し、バックエンドはメッセージを永続的に保存する.
簡単なコード実装demoは以下の通りです.
1、pom.xmlプライマリ構成
2、springコア構成情報
3、websocketサービス側実現
4、websocket接続前後のイベントクラス
//The extension[x-webkit-deflate-frame]is not supported問題if(request.getHeaders()を解決する.containsKey("Sec-WebSocket-Extensions")) { request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate"); }
このうち赤色のコードは次のエラーを解決するためで、ios携帯電話safariブラウザバージョンの問題による可能性があります.
org.springframework.web.socket.server.HandshakeFailureException: Uncaught failure for request http://localhost:8080/spring4/myHandler; nested exception is java.lang.IllegalArgumentException: The extension [x-webkit-deflate-frame] is not supported
5、websocketメッセージ処理クラス
6、クライアントページ
この例も他の人のコードに基づいていくつかの修正を行い、バグを修正しました.
完全なdemoの友達を要してここをダウンロードすることができます
エンジニアリング環境:tomcat 8+jdk 1.7+maven+eclipse
設計構想:クライアントがホームページにログインしてsocket接続を確立し、バックグラウンドにユーザー接続情報を記録し、標識を行う.ユーザがウェブページ側でチャットメッセージをバックグラウンドに送信すると、バックグラウンドは情報を受信した後、メッセージを受信者に送信し、バックエンドはメッセージを永続的に保存する.
簡単なコード実装demoは以下の通りです.
1、pom.xmlプライマリ構成
javax.websocket
javax.websocket-api
1.0
provided
org.springframework
spring-websocket
${spring.version}
org.springframework
spring-messaging
${spring.version}
org.springframework
spring-aop
${spring.version}
org.apache.logging.log4j
log4j-api
${log4j.version}
org.apache.logging.log4j
log4j-core
${log4j.version}
org.springframework
spring-aspects
${spring.version}
2、springコア構成情報
3、websocketサービス側実現
package com.milanosoft.RCS.web.webSocket.config;
import com.milanosoft.RCS.web.webSocket.hndler.SystemWebSocketHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import com.milanosoft.RCS.web.webSocket.interceptor.HandshakeInterceptor;
import org.springframework.context.annotation.Bean;
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements
WebSocketConfigurer {
public WebSocketConfig() {
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(systemWebSocketHandler(), "/websck").addInterceptors(new HandshakeInterceptor());
System.out.println("registed!");
registry.addHandler(systemWebSocketHandler(), "/sockjs/websck").addInterceptors(new HandshakeInterceptor())
.withSockJS();
}
@Bean
public WebSocketHandler systemWebSocketHandler() {
//return new InfoSocketEndPoint();
return new SystemWebSocketHandler();
}
}
4、websocket接続前後のイベントクラス
package com.milanosoft.RCS.web.webSocket.interceptor;
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.support.HttpSessionHandshakeInterceptor;
@Component
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
// The extension [x-webkit-deflate-frame] is not supported
if(request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
}
System.out.println("Before Handshake");
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
System.out.println("After Handshake");
super.afterHandshake(request, response, wsHandler, ex);
}
}
//The extension[x-webkit-deflate-frame]is not supported問題if(request.getHeaders()を解決する.containsKey("Sec-WebSocket-Extensions")) { request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate"); }
このうち赤色のコードは次のエラーを解決するためで、ios携帯電話safariブラウザバージョンの問題による可能性があります.
org.springframework.web.socket.server.HandshakeFailureException: Uncaught failure for request http://localhost:8080/spring4/myHandler; nested exception is java.lang.IllegalArgumentException: The extension [x-webkit-deflate-frame] is not supported
5、websocketメッセージ処理クラス
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.milanosoft.RCS.web.webSocket.hndler;
import org.springframework.stereotype.Component;
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;
/**
*
* @author lzk
*/
@Component
public class SystemWebSocketHandler implements WebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("connect to the websocket success......");
session.sendMessage(new TextMessage("Server:connected OK!"));
}
@Override
public void handleMessage(WebSocketSession wss, WebSocketMessage> wsm) throws Exception {
TextMessage returnMessage = new TextMessage(wsm.getPayload()
+ " received at server");
System.out.println(wss.getHandshakeHeaders().getFirst("Cookie"));
wss.sendMessage(returnMessage);
}
@Override
public void handleTransportError(WebSocketSession wss, Throwable thrwbl) throws Exception {
if(wss.isOpen()){
wss.close();
}
System.out.println("websocket connection closed......");
}
@Override
public void afterConnectionClosed(WebSocketSession wss, CloseStatus cs) throws Exception {
System.out.println("websocket connection closed......");
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
6、クライアントページ
WebSocket/SockJS Echo Sample (Adapted from Tomcat's echo sample)
var ws = null;
var url = null;
var transports = [];
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('echo').disabled = !connected;
}
function connect() {
//alert(url);
//console.log(url);
if (!url) {
alert('Select whether to use W3C WebSocket or SockJS');
return;
}
//ws = (url.indexOf('sockjs') != -1) ?new SockJS(url, undefined, {protocols_whitelist: transports}) : new WebSocket(url);
if ('WebSocket' in window) {
ws= new WebSocket("ws://192.168.1.104:8080/SpringWebSocketPush/websck");
console.log("ws://192.168.1.104:8080/SpringWebSocketPush/websck");
}else {
ws = new SockJS("http://192.168.1.104:8080/SpringWebSocketPush/sockjs/websck");
console.log("http://192.168.1.104:8080/SpringWebSocketPush/sockjs/websck");
}
//websocket = new SockJS("http://localhost:8080/SpringWebSocketPush/sockjs/websck");
ws.onopen = function () {
alert('open');
setConnected(true);
//log('Info: connection opened.');
};
ws.onmessage = function (event) {
alert('Received:' + event.data);
log('Received: ' + event.data);
};
ws.onclose = function (event) {
setConnected(false);
log('Info: connection closed.');
log(event);
};
}
function disconnect() {
if (ws != null) {
ws.close();
ws = null;
}
setConnected(false);
}
function echo() {
if (ws != null) {
var message = document.getElementById('message').value;
log('Sent: ' + message);
ws.send(message);
} else {
alert('connection not established, please connect.');
}
}
function updateUrl(urlPath) {
if (urlPath.indexOf('sockjs') != -1) {
url = urlPath;
document.getElementById('sockJsTransportSelect').style.visibility = 'visible';
}
else {
if (window.location.protocol == 'http:') {
url = 'ws://' + window.location.host + urlPath;
} else {
url = 'wss://' + window.location.host + urlPath;
}
document.getElementById('sockJsTransportSelect').style.visibility = 'hidden';
}
}
function updateTransport(transport) {
alert(transport);
transports = (transport == 'all') ? [] : [transport];
}
function log(message) {
var console = document.getElementById('console');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(message));
console.appendChild(p);
while (console.childNodes.length > 25) {
console.removeChild(console.firstChild);
}
console.scrollTop = console.scrollHeight;
}
SockJS transport:
この例も他の人のコードに基づいていくつかの修正を行い、バグを修正しました.
完全なdemoの友達を要してここをダウンロードすることができます