tomcat 7.0.68ベースのwebsocket実装、およびHttpSessionIdによるwebsocketセッション共有
0、ページ呼び出しコードを貼っておきます
1、onlineWebsocket.java
2、RealWebsocket.java
3、最後はhttpSessionIdによるwebsocket session共有
まずRealWebSocket.javaとOnlineWebsocketに登場したGetHttpSessionConfigurator.classを実現する
上のフィルターの中で、もし意外でなければ、あなたは空のポインタを報告します.だから、ここで修復します.
また、このフィルタをweb.xmlに追加します.
これで終わったら、何の問題もないはずです.
OnlineWebsocket.javaとRealWebsocket.javaのhttpSessionWebSocketMap変数で2つのwebssocket Session共有を実現します.
var historyWebsocket = null;
// var websocketOnline = null;
// WebSocket
if('WebSocket' in window){
historyWebsocket = new WebSocket("ws://ip: / /historyWebsocket");
}
else{
alert('Not support websocket')
}
//
historyWebsocket.onerror = function(){
setMessageInnerHTML("error");
};
//
historyWebsocket.onopen = function(event){
send();
}
//
historyWebsocket.onmessage = function(event){
var data = eval("("+event.data+")");//
}
//
historyWebsocket.onclose = function(){
setMessageInnerHTML("close");
}
// , , websocket , ,server 。
window.onbeforeunload = function(){
historyWebsocket.close();
}
//
function setMessageInnerHTML(innerHTML){
$("#message").empty();
document.getElementById('message').innerHTML +='' +innerHTML + '
';
}
//
function closeWebSocket(){
historyWebsocket.close();
}
//
function send(){
// var message = document.getElementById('text').value;
// mesg="14701661345";
// historyWebsocket.send(message);
}
1、onlineWebsocket.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// URI, URI WebSocket。 Servlet mapping。 web.xml 。
@ServerEndpoint(value="/onlineWebsocket",configurator=GetHttpSessionConfigurator.class)
public class OnlineStateWebSocket {
private static final Logger LOG = LoggerFactory.getLogger(OnlineStateWebSocket.class);
// , 。 。
private static int onlineCount = 0;
//concurrent Set, MyWebSocket 。 , Map , Key
private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();
// sim session map ,key sim ,value session
private static ConcurrentHashMap> simSessionWebSocketMap = new ConcurrentHashMap>();
// httpSessionId/session map ,key httpSessionId ,value session
private static ConcurrentHashMap httpSessionWebSocketMap = new ConcurrentHashMap();
// ,
private Session session;
private HttpSession httpSession;
/**
*
* @param session 。session ,
*/
@OnOpen
public void onOpen(Session session, EndpointConfig config){
this.session = session;
webSocketSet.add(this); // set
addOnlineCount(); // 1
this.httpSession = (HttpSession) config.getUserProperties()
.get(HttpSession.class.getName());
// httpSession
httpSessionWebSocketMap.put(this.httpSession.getId(), this);
System.out.println(" : ! " + getOnlineCount());
}
/**
*
*/
@OnClose
public void onClose(){
webSocketSet.remove(this); // set
subOnlineCount(); // 1
Set>> entrySet = simSessionWebSocketMap.entrySet();
Iterator>> iterator = entrySet.iterator();
while(iterator.hasNext()){
Entry> next = iterator.next();
String key = next.getKey(); // sim
ArrayList value = next.getValue(); // sim websocket
if(value.contains(this)){
if(value.size()>1){
value.remove(this);
simSessionWebSocketMap.replace(key, value);
}else{
simSessionWebSocketMap.remove(key);
}
}
}
System.out.println(" : ! " + getOnlineCount());
}
/**
*
* @param message
* @param session
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println(" : :" + message);
String[] SimArray = message.split(",");
this.session = session;
webSocketSet.add(this); // set
for(String sim:SimArray){
ArrayList vehicleClientList ;
if(simSessionWebSocketMap.get(sim.trim()) != null){
vehicleClientList=simSessionWebSocketMap.get(sim.trim()); // sim session
vehicleClientList.add(this);
simSessionWebSocketMap.replace(sim.trim(), vehicleClientList);
}else{
vehicleClientList= new ArrayList();
vehicleClientList.add(this);
simSessionWebSocketMap.put(sim.trim(), vehicleClientList);
}
}
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
System.out.println(" : ");
error.printStackTrace();
}
/**
* 。 , 。
* @param message
* @throws IOException
*/
public void sendMessage(String message,HttpServletRequest request) throws IOException{
if(this.session.isOpen()){
this.session.getBasicRemote().sendText(message);
this.session.setMaxTextMessageBufferSize(102400);
// this.session.getAsyncRemote().sendText(message);
}
}
public void sendMessage(String message) throws IOException{
if(this.session.isOpen()){
this.session.getBasicRemote().sendText(message);
this.session.setMaxTextMessageBufferSize(102400);
// this.session.getAsyncRemote().sendText(message);
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
OnlineStateWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount() {
OnlineStateWebSocket.onlineCount--;
}
public static CopyOnWriteArraySet getWebSocketSet() {
return webSocketSet;
}
public static void setWebSocketSet(CopyOnWriteArraySet webSocketSet) {
OnlineStateWebSocket.webSocketSet = webSocketSet;
}
}
2、RealWebsocket.java
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// URI, URI WebSocket。 Servlet mapping。 web.xml 。
@ServerEndpoint(value ="/realWebsocket",configurator=GetHttpSessionConfigurator.class)
public class RealWebSocket {
private static final Logger LOG = LoggerFactory.getLogger(RealLocationWebSocket.class);
// , 。 。
private static int onlineCount = 0;
//concurrent Set, MyWebSocket 。 , Map , Key
private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();
// sim session map ,key sim ,value session
private static ConcurrentHashMap> simSessionWebSocketMap = new ConcurrentHashMap>();
// httpSessionId/session map ,key httpSessionId ,value session
private static ConcurrentHashMap httpSessionWebSocketMap = new ConcurrentHashMap();
// ,
private Session session;
private HttpSession httpSession;
/**
*
* @param session 。session ,
*/
@OnOpen
public void onOpen(Session session, EndpointConfig config){
this.session = session;
webSocketSet.add(this); // set
addOnlineCount(); // 1
this.httpSession = (HttpSession) config.getUserProperties()
.get(HttpSession.class.getName());
// httpSession
httpSessionWebSocketMap.put(this.httpSession.getId(), this);
System.out.println(" : ! " + getOnlineCount());
}
/**
*
*/
@OnClose
public void onClose(){
webSocketSet.remove(this); // set
subOnlineCount(); // 1
Set>> entrySet = simSessionWebSocketMap.entrySet();
Iterator>> iterator = entrySet.iterator();
while(iterator.hasNext()){
Entry> next = iterator.next();
String key = next.getKey(); // sim
ArrayList value = next.getValue(); // sim websocket
if(value.contains(this)){
if(value.size()>1){
value.remove(this);
simSessionWebSocketMap.replace(key, value);
}else{
simSessionWebSocketMap.remove(key);
}
}
}
System.out.println(" : ! " + getOnlineCount());
}
/**
*
* @param message
* @param session
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println(" : :" + message);
String[] SimArray = message.split(",");
this.session = session;
webSocketSet.add(this); // set
for(String sim:SimArray){
ArrayList vehicleClientList ;
if(simSessionWebSocketMap.get(sim.trim()) != null){
vehicleClientList=simSessionWebSocketMap.get(sim.trim()); // sim session
vehicleClientList.add(this);
simSessionWebSocketMap.replace(sim.trim(), vehicleClientList);
}else{
vehicleClientList= new ArrayList();
vehicleClientList.add(this);
simSessionWebSocketMap.put(sim.trim(), vehicleClientList);
}
}
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
System.out.println(" : ");
error.printStackTrace();
}
/**
* 。 , 。
* @param message
* @throws IOException
*/
public void sendMessage(String message,HttpServletRequest request) throws IOException{
if(this.session.isOpen()){
this.session.getBasicRemote().sendText(message);
this.session.setMaxTextMessageBufferSize(102400);
// this.session.getAsyncRemote().sendText(message);
}
}
public void sendMessage(String message) throws IOException{
if(this.session.isOpen()){
this.session.getBasicRemote().sendText(message);
this.session.setMaxTextMessageBufferSize(102400);
// this.session.getAsyncRemote().sendText(message);
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
RealLocationWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount() {
RealLocationWebSocket.onlineCount--;
}
public static CopyOnWriteArraySet getWebSocketSet() {
return webSocketSet;
}
public static void setWebSocketSet(CopyOnWriteArraySet webSocketSet) {
RealLocationWebSocket.webSocketSet = webSocketSet;
}
}
3、最後はhttpSessionIdによるwebsocket session共有
まずRealWebSocket.javaとOnlineWebsocketに登場したGetHttpSessionConfigurator.classを実現する
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import javax.websocket.Extension;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator
{
@Override
public T getEndpointInstance(Class clazz)
throws InstantiationException {
try {
return clazz.newInstance();
} catch (IllegalAccessException e) {
InstantiationException ie = new InstantiationException();
ie.initCause(e);
throw ie;
}
}
@Override
public String getNegotiatedSubprotocol(List supported,
List requested) {
for (String request : requested) {
if (supported.contains(request)) {
return request;
}
}
return "";
}
@Override
public List getNegotiatedExtensions(List installed,
List requested) {
List result = new ArrayList<>();
for (Extension request : requested) {
if (installed.contains(request)) {
result.add(request);
}
}
return result;
}
@Override
public boolean checkOrigin(String originHeaderValue) {
return true;
}
@Override
public void modifyHandshake(ServerEndpointConfig config,
HandshakeRequest request,
HandshakeResponse response)
{
HttpSession httpSession = (HttpSession)request.getHttpSession();
config.getUserProperties().put(HttpSession.class.getName(),httpSession);
}
}
上のフィルターの中で、もし意外でなければ、あなたは空のポインタを報告します.だから、ここで修復します.
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
// TODO Auto-generated method stub
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpSession session = ((HttpServletRequest) sre.getServletRequest()).getSession();
}
}
また、このフィルタをweb.xmlに追加します.
com.vshop.sys.listener.RequestListener
これで終わったら、何の問題もないはずです.
OnlineWebsocket.javaとRealWebsocket.javaのhttpSessionWebSocketMap変数で2つのwebssocket Session共有を実現します.