zoukankan      html  css  js  c++  java
  • 解决浏览器跨域限制方案之WebSocket

    WebSocket是在HTML5中引入的浏览器与服务端的通信协议,可以类比HTTP。
    可以在支持HTML5的浏览器版本中使用WebSocket进行数据通信,常见的案例是使用WebSocket进行实时数据刷新。
    关于WebSocket详细的功能性描述,详见:https://zh.wikipedia.org/wiki/WebSocket。
    在这里主要说明在tomcat中如何编写WebSocket服务端程序。

    从tomcat7开始支持WebSocket,但是从tomcat8之后使用了关于WebSocket的注解,就得WebSocket API废弃不用。
    所以,需要分别按tomcat7和tomcat8+来说明如何使用WebSocket。

    tomcat7使用websocket

    <!-- tomcat7中实现websocket: 定义servlet -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-catalina</artifactId>
        <version>7.0.39</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-coyote</artifactId>
        <version>7.0.39</version>
        <scope>provided</scope>
    </dependency>
    

    在tomcat7中实现WebSocket服务端,与编写一个Servlet程序是一样的。

    /**
     * tomcat7中实现websocket servlet
     * @desc org.chench.test.web.websocket.WsServlet
     * @author chench9@lenovo.com
     * @date 2017年10月9日
     */
    public class WsChatServlet extends WebSocketServlet {
    	private static final long serialVersionUID = 1L;
    	private static final Logger logger = LoggerFactory.getLogger(WsChatServlet.class);
    	
    	private List<MyMessageInBound> milist = new ArrayList<MyMessageInBound>(); // 客户端列表
    
    	/**
    	 * 对应每一个客户端连接都创建不同的对象处理
    	 */
    	@Override
    	protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest arg1) {
    		return new MyMessageInBound();
    	}
    	
    	/**
    	 * 处理客户端WebSocket连接请求
    	 * @desc org.chench.test.web.websocket.MyMessageInBound
    	 * @author chench9@lenovo.com
    	 * @date 2017年10月9日
    	 */
    	private class MyMessageInBound extends MessageInbound {
    		private WsOutbound wso = null;
    
    		@Override
    		protected void onBinaryMessage(ByteBuffer message) throws IOException {
    			if(logger.isDebugEnabled()) {
    				logger.debug("onBinaryMessage");
    			}
    			// do nothing
    		}
    
    		@Override
    		protected void onTextMessage(CharBuffer message) throws IOException {
    			if(logger.isDebugEnabled()) {
    				logger.debug("onTextMessage");
    			}
    			
    			for(MyMessageInBound mmib : milist) {
    				CharBuffer buffer =	CharBuffer.wrap(message);
    				mmib.getWsOutbound().writeTextMessage(buffer);
    				mmib.getWsOutbound().flush();
    			}
    		}
    
    		@Override
    		protected void onOpen(WsOutbound outbound) {
    			if(logger.isDebugEnabled()) {
    				logger.debug("websocket client connection add");
    			}
    			this.wso = outbound;
    			milist.add(this);
    			try {
    				outbound.writeTextMessage(CharBuffer.wrap("Hello"));
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    			
    			logger.info("websocket client list size: {}", milist.size());
    			
    		}
    
    		@Override
    		protected void onClose(int status) {
    			if(logger.isDebugEnabled()) {
    				logger.debug("websocket client closed! {}", this.wso.toString());
    			}
    			milist.remove(this);
    		}
    	}
    }
    

    最后在web.xml文件中配置该Servlet即可。

    tomcat8+使用websocket

    特别注意: tomcat7中的WebSocket API在tomcat8之后就已经废弃,要根据实际的运行环境选择对应实现。

    在tomcat8之后,使用了新的WebSocket API。具体来说,是通过注解方式编写WebSocket服务端。

    <!-- 在tomcat8中实现websocket: 使用注解 -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-websocket-api</artifactId>
        <version>8.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-websocket</artifactId>
        <version>8.0.1</version>
    </dependency>
    
    /**
     * 在tomcat8+中实现websocket,通过注解
     * @desc org.chench.test.web.websocket.WsChatAnnotation
     * @author chench9@lenovo.com
     * @date 2017年10月9日
     */
    @ServerEndpoint(value="/ws/chatAnnotation")
    public class WsChatAnnotation {
    	private static final Logger logger = LoggerFactory.getLogger(WsChatAnnotation.class);
    	
    	private static final AtomicInteger counter = new AtomicInteger(0);                                    // 客户端计数器
    	private static final Set<WsChatAnnotation> connections = new CopyOnWriteArraySet<WsChatAnnotation>(); // 客户端websocket连接
    	private Session session = null;
    	private Integer number = 0;                                                                           // 客户端编号
    
    	public WsChatAnnotation() {
    		number = counter.incrementAndGet();
    	}
    	
    	/**
    	 * 客户端建立websocket连接
    	 * @param session
    	 */
    	@OnOpen
    	public void start(Session session) {
    		logger.info("on open");
    		this.session = session;
    		connections.add(this);
    		try {
    			session.getBasicRemote().sendText(new StringBuffer().append("Hello: ").append(number).toString());
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 客户端断开websocket连接
    	 */
    	@OnClose
    	public void close() {
    		logger.info("session close");
    		try {
    			this.session.close();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			connections.remove(this);
    		}
    	}
    	
    	/**
    	 * 接收客户端发送的消息
    	 * @param message
    	 */
    	@OnMessage
    	public void message(String message) {
    		logger.info("message");
    		logger.info("message: {}", message);
    		
    		for(WsChatAnnotation client : connections) {
    			synchronized (client) {
    				try {
    					client.session.getBasicRemote().sendText(message);
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		// end for
    	}
    	
    	@OnError
    	public void error(Throwable t) {
    		logger.error("client: {} error", number, t);
    	}
    }
    

    【参考】
    http://www.cnblogs.com/xdp-gacl/p/5193279.html Java后端WebSocket的Tomcat实现
    http://blog.fens.me/java-websocket-intro/ Java现实WebSocket
    http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html tomcat7 web socket
    http://tomcat.apache.org/tomcat-8.0-doc/web-socket-howto.html tomcat8 web socket
    https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket WebSocket对象api
    https://www.zhihu.com/question/20215561 WebSocket 是什么原理?为什么可以实现持久连接?
    https://www.nginx.com/blog/websocket-nginx/ NGINX as a WebSocket Proxy

  • 相关阅读:
    基于express框架的Token实现方案
    书籍整理
    openfire4.0.2开发环境搭建(windows)
    Express4.x动态的销毁或者替换中间件(app.unuse)
    mysql学习笔记(三)----函数
    mysql学习笔记(二)----数据类型
    mysql学习笔记(一)----建表操作
    Windows-mysql5.7安装
    JavaScript学习笔记–(new关键字)
    n枚硬币问题(找假币)
  • 原文地址:https://www.cnblogs.com/nuccch/p/7496203.html
Copyright © 2011-2022 走看看