前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解决浏览器跨域限制方案之WebSocket

解决浏览器跨域限制方案之WebSocket

作者头像
编程随笔
发布2019-09-11 15:58:09
1.7K0
发布2019-09-11 15:58:09
举报
文章被收录于专栏:后端开发随笔后端开发随笔

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

代码语言:javascript
复制
<!-- 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程序是一样的。

代码语言:javascript
复制
/**
 * 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服务端。

代码语言:javascript
复制
<!-- 在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>
代码语言:javascript
复制
/**
 * 在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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-09-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • tomcat7使用websocket
  • tomcat8+使用websocket
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档