Spring 4+tomcat 8+jdk 8アプリケーションwebsocket
8994 ワード
環境JDK 8.0 + Spring4.2.3 + Tomcat8.0
websocketはhtml 5の特性の一つであり、既存の主流のブラウザはすでにwebsocketをサポートしており、websocketもJava EE 7の規範の一つとなっている.現在jetty、tomcatなどの主流のアプリケーションサーバはwebsocketプロトコルをサポートしている.tomcatは7以上でwebsocketプロトコルをサポートしていますが、tomcat 7とtomcat 8は少し違います.tomcat 8はwebsocketに対してもっと良い支持とサンプルがあって、webappexamplesの下にwebsocketのサンプルがあって、直接実行することができて、javaファイルはexampleのWEB-INFディレクトリの下で、classと一緒に置いて、とても便利です.
Spring 4もwebsocketに対するAPIサポートを追加し、現在一部のコンテナはJSR-356仕様に対してまだ実現されていないが、異なるバージョンのコンテナ実現方式も異なり、springが提供するAPIを使用してwebsocketの開発を統一することができる.
一.JAVA API for websocket JSR-356
1.非常に簡単で、サーバーセグメントは@ServerEndpoint IDを使用するだけで、具体的な使用方法:
Websocketサービスに設定する必要があるクラスに@Server Endpoint(value='abcd')を追加し、対応するメソッドを実装すればよい.
2.クライアントインタフェースでの使用
もちろん複雑な点でもブラウザがwebsocketをサポートしているかどうかを判断することができ、tomcat 8のサンプルを参考にすることができます.
3.使用するパッケージ
JAVA APIのみを使用する場合はtomcatの下のwebsocket-apiをインポートする必要がある.JArは、これまでtomcatとの実装を比較する、直接インポートはまだだめであり、tomcatの下のwebsocket-apiを直接インポートする.jar、配備が実行されると、ずっとエラーが報告されています.Error during WebSocket handshake : Unexpected response code : 404.これはjarパケットが衝突したためだそうです.
解決方法:既存のプロジェクトのjava ee 7を削除する.JArパッケージ、tomcatの中のwebsocket-api.JArパッケージは1つのディレクトリに個別にコピーされ、tomcat-websocketと名付けられ、プロジェクトで右クリック->propertiesJava->Build Path->Libraries->Add Library->User Library->User Libraries->New->User library name tomcat-websocketを入力し、下のsystem library->ok->先ほど追加したtomcat-websocketを選択し、Add External JARsをクリックします.さっきコピーしたwebsocket-apiに参加します.JArのディレクトリtomcat-websocket->作成したUser library->Finishをチェックします.
作成してからインポートするとjavax-websocketのパッケージが現れ、tomcat 8に配備して実行できます.
二、Spring API for WebSocket
Javaのapiを使うのは面倒ではありませんが、Springでは上記の手順を処理する必要はありません.Springは4からWebSocket APIを発売し、現在はSpring 4を使用している.2.3、比較的新しいバージョンです.もちろん上記JAVA API for websocket'はSpringエンジニアリングでも使用できますが、アプリケーションサーバjarパッケージとの競合に注意が必要です.
1. WebSocketConfig
Springは1つの構成クラスを通じてwebsoceketサービスを登録し管理する
2.Interceptor、その名の通り、インターセプタ、HandshakeInterceptorインタフェースを実現し、websocket握手開始と握手終了のイベントを処理する.
3.
RealSocketHandlerは、WebSocketHandlerインタフェースを実現し、具体的なwebsocket情報インタラクティブコンテンツを処理する.
websocketはhtml 5の特性の一つであり、既存の主流のブラウザはすでにwebsocketをサポートしており、websocketもJava EE 7の規範の一つとなっている.現在jetty、tomcatなどの主流のアプリケーションサーバはwebsocketプロトコルをサポートしている.tomcatは7以上でwebsocketプロトコルをサポートしていますが、tomcat 7とtomcat 8は少し違います.tomcat 8はwebsocketに対してもっと良い支持とサンプルがあって、webappexamplesの下にwebsocketのサンプルがあって、直接実行することができて、javaファイルはexampleのWEB-INFディレクトリの下で、classと一緒に置いて、とても便利です.
Spring 4もwebsocketに対するAPIサポートを追加し、現在一部のコンテナはJSR-356仕様に対してまだ実現されていないが、異なるバージョンのコンテナ実現方式も異なり、springが提供するAPIを使用してwebsocketの開発を統一することができる.
一.JAVA API for websocket JSR-356
1.非常に簡単で、サーバーセグメントは@ServerEndpoint IDを使用するだけで、具体的な使用方法:
Websocketサービスに設定する必要があるクラスに@Server Endpoint(value='abcd')を追加し、対応するメソッドを実装すればよい.
import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.server.ServerEndpoint;
import org.springframework.context.annotation.Configuration;
@Configuration
@ServerEndpoint(value = "/abcd")
public class RealEndpoint {
@OnOpen
public void onOpen() {
System.out.println("Client connected");
}
@OnClose
public void onClose() {
System.out.println("Connection closed");
}
}
2.クライアントインタフェースでの使用
var host = 'ws://' + window.location.host + '/THSCADAWEB/collectionList';
var webSocket;
if ('WebSocket' in window) {
webSocket = new WebSocket(host);
} else if ('MozWebSocket' in window) {
webSocket = new MozWebSocket(host);
} else {
Ext.Msg.alert(' ', ' websocket, ');
return;
}
webSocket.onerror = function(event) {
console.log('error');
};
webSocket.onopen = function(event) {
console.log('open');
};
webSocket.onmessage = function(event) {
var data = event.data;
console.log('onmessage');
var address = data.split(';')[0];
var status = data.split(';')[1];
var collectionStore = Ext.getCmp('deployCollectionGrid').getStore();
var rec = collectionStore.findExact('remote_address', address);
if(rec > -1){
unit = collectionStore.getAt(rec).set('collection_connStatus',status);
}else{
collectionStore.add({
'remote_address' : address,
'collection_connStatus' : status
});
}
};
もちろん複雑な点でもブラウザがwebsocketをサポートしているかどうかを判断することができ、tomcat 8のサンプルを参考にすることができます.
3.使用するパッケージ
JAVA APIのみを使用する場合はtomcatの下のwebsocket-apiをインポートする必要がある.JArは、これまでtomcatとの実装を比較する、直接インポートはまだだめであり、tomcatの下のwebsocket-apiを直接インポートする.jar、配備が実行されると、ずっとエラーが報告されています.Error during WebSocket handshake : Unexpected response code : 404.これはjarパケットが衝突したためだそうです.
解決方法:既存のプロジェクトのjava ee 7を削除する.JArパッケージ、tomcatの中のwebsocket-api.JArパッケージは1つのディレクトリに個別にコピーされ、tomcat-websocketと名付けられ、プロジェクトで右クリック->propertiesJava->Build Path->Libraries->Add Library->User Library->User Libraries->New->User library name tomcat-websocketを入力し、下のsystem library->ok->先ほど追加したtomcat-websocketを選択し、Add External JARsをクリックします.さっきコピーしたwebsocket-apiに参加します.JArのディレクトリtomcat-websocket->作成したUser library->Finishをチェックします.
作成してからインポートするとjavax-websocketのパッケージが現れ、tomcat 8に配備して実行できます.
二、Spring API for WebSocket
Javaのapiを使うのは面倒ではありませんが、Springでは上記の手順を処理する必要はありません.Springは4からWebSocket APIを発売し、現在はSpring 4を使用している.2.3、比較的新しいバージョンです.もちろん上記JAVA API for websocket'はSpringエンジニアリングでも使用できますが、アプリケーションサーバjarパッケージとの競合に注意が必要です.
1. WebSocketConfig
Springは1つの構成クラスを通じてwebsoceketサービスを登録し管理する
package com.th.scada.websocket;
import org.springframework.context.annotation.Bean;
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.th.scada.real.controller.RealSocketHandler;
/**
* Spring WebSocket
* @author guoyankun
*/
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements
WebSocketConfigurer {
/**
* websocket
*/
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// websocket ,addHandler websocket , collectionList endpoint
registry.addHandler(RealSocketHandler(), "/collectionList").addInterceptors(new WebSocketHandshakeInterceptor());
// websocket endpoint
}
@Bean
public WebSocketHandler RealSocketHandler() {
return new RealSocketHandler();
}
}
2.Interceptor、その名の通り、インターセプタ、HandshakeInterceptorインタフェースを実現し、websocket握手開始と握手終了のイベントを処理する.
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 com.th.scada.util.Constants;
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {
private static Logger logger = LoggerFactory.getLogger(HandshakeInterceptor.class);
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
if (session != null) {
// userName WebSocketHandler,
String userName = (String) session.getAttribute(Constants.SESSION_USERNAME);
if(userName != null){
attributes.put(Constants.WEBSOCKET_USERNAME,userName);
}
}
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
}
3.
RealSocketHandlerは、WebSocketHandlerインタフェースを実現し、具体的なwebsocket情報インタラクティブコンテンツを処理する.
import java.io.IOException;
import java.util.ArrayList;
import org.apache.log4j.Logger;
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;
public class RealSocketHandler implements WebSocketHandler {
private static final ArrayList users = new ArrayList();
private static Logger logger = Logger.getLogger(RealSocketHandler.class);
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus arg1) throws Exception {
logger.debug("websocket connection closed");
System.out.println("afterConnectionClosed");
users.remove(session);
}
@Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
logger.debug("connect to the websocket succcess ... ...");
System.out.println("afterConnectionEstablished");
users.add(session);
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage> arg1) throws Exception {
System.out.println("handleMessage");
}
@Override
public void handleTransportError(WebSocketSession session, Throwable arg1) throws Exception {
System.out.println("handleTransportError");
logger.debug("websocket connection closed");
users.remove(session);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
*
*
* @param message
*
*/
public void sendMessageToUsers(TextMessage message) {
for (WebSocketSession user : users) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*
*
* @param userName
* @param message
*/
public void sendMessageToUser(String userName, TextMessage message) {
for (WebSocketSession user : users) {
if (user.getAttributes().get("websocket_username").equals(userName)) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
}
4. Spring API for WebSocketを使用するとtomcatのwebsocket-apiは必要ありません.JArパッケージはspring-websocket-4.2.3に代わります.RELEASE.jar.