`
85977328
  • 浏览: 1870975 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

WEB开发服务器推送技术-tomcat7之websocket

 
阅读更多
从tomcat7.0.26之后开始支持websocket,建议大家使用tomcat7.0.30,期间版本的接口有一些改动。chrome默认支持websocket。其他浏览器可能由于安全原因,默认是关闭的。

package com.panguso.phl.servlet;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.logging.Logger;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;

/**
 * 
 * @author piaohailin
 * 2012-09-08
 *
 */
@WebServlet(urlPatterns = "/echo.ws")
// 处理WebSocket的Servlet需要继承自WebSocketServlet,这一点和7.0.27仍然一样
public class EchoServlet extends WebSocketServlet {
    // Log
    private Logger logger = Logger.getLogger(EchoServlet.class.getName());

    @Override
    // 与7.0.27不同的,Tomcat改变了createWebSocketInbound方法的定义,增加了一个HttpServletRequest参数
    // 这样我们也可以从request参数中获取更多请求方的信息
    protected StreamInbound createWebSocketInbound(String subProtocol,
                                                   HttpServletRequest request) {
        // Log
        //        logger.setLevel(java.util.logging.Level.ALL);
        logger.info("request ws servlet");

        // 方法仍然是返回一个StreamInbound实例,这里采用实现他的子类MessageInbound
        // 只用实现下面四个事件处理函数(其实onClose和onOpen有缺省实现)
        return new MessageInbound() {
            // WebSocket关闭事件,参数status应该来自org.apache.catalina.websocket.Constants中定义的几个常量,可以参考文档或者核对一下Tomcat的源码
            @Override
            protected void onClose(int status) {
                // Log
                logger.info("Web Socket Closed: " + status);
            }

            // WebSocket握手完成,创建完毕,WsOutbound用于向客户端发送数据
            @Override
            protected void onOpen(WsOutbound outbound) {
                // Log
                logger.info("Web Socket Open!");
            }

            // 有二进制消息数据到达,暂时没研究出这个函数什么情况下触发,js的WebSocket按理说应该只能send文本信息才对
            @Override
            protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
                // Log
                logger.info("Binary Message Receive: " + buffer.remaining());
                // Nothing
            }

            // 有文本消息数据到达
            @Override
            protected void onTextMessage(CharBuffer buffer) throws IOException {
                // Log
                logger.info("Text Message Receive: " + buffer.remaining());
                // getWsOutbound可以返回当前的WsOutbound,通过他向客户端回传数据,这里采用的是nio的CharBuffer
                getWsOutbound().writeTextMessage(buffer);
                
                //模拟服务器通知浏览器,从浏览器就会看,每3秒收到1条服务器消息
                //                for (int i = 0; i < 3; i++) {
                //                    try {
                //                        Thread.sleep(3000);
                //                    } catch (InterruptedException e) {
                //                        // TODO Auto-generated catch block
                //                        e.printStackTrace();
                //                    }
                //                    getWsOutbound().writeTextMessage(CharBuffer.wrap(String.valueOf(i).subSequence(0, 1)));
                //                }

            }
        };
    }
}



index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	var ws = null;

	function startServer() {
		// 设定WebSocket,注意协议是ws,请求是指向对应的WebSocketServlet的
		var url = "ws://127.0.0.1:8080/echo.ws";
		// 创建WebSocket实例,下面那个MozWebSocket是Firefox的实现
		if ('WebSocket' in window) {
			ws = new WebSocket(url);
		} else if ('MozWebSocket' in window) {
			ws = new MozWebSocket(url);
		} else {
			alert('Unsupported.');
			return;
		}

		// WebSocket握手完成,连接成功的回调
		// 有个疑问,按理说new WebSocket的时候就会开始连接了,如果在设置onopen以前连接成功,是否还会触发这个回调
		ws.onopen = function() {
			alert('Opened!');
		};

		// 收到服务器发送的文本消息, event.data表示文本内容
		ws.onmessage = function(event) {
			alert('Receive message: ' + event.data);
		};

		// 关闭WebSocket的回调
		ws.onclose = function() {
			alert('Closed!');
		};
	}

	function sendMyMessage() {
		var textMessage = document.getElementById('textMessage').value;

		if (ws != null && textMessage != '') {
			// 通过WebSocket想向服务器发送一个文本信息
			ws.send(textMessage);
		}
	}
</script>
</head>
<body>
<body onload="startServer()">
<input type="text" id="textMessage" size="20" />
<input type="button" onclick="sendMyMessage()" value="Send">
</body>
</html>

5
0
分享到:
评论
9 楼 allan_chan 2013-11-08  
cqcya 写道
我在本机能够访问,但是从别的机器上访问总提示“closed",不知道是什么原因?

有没有连到你的服务器
8 楼 yanjingjiangjun 2013-06-28  
html5  blob文件发送会用到onBinaryMessage
7 楼 cqcya 2013-05-20  
我在本机能够访问,但是从别的机器上访问总提示“closed",不知道是什么原因?
6 楼 netkiller.github.com 2012-09-14  
xiaozan 写道
请问,这个技术在应用方面可以做哪些功能


即时通信,聊天室,信息通知,等等

例如:可以实现XAMPP做即时通信,直接操作POP,SMTP实现web收发邮件。无需服务端程序介入
5 楼 wukele 2012-09-08  
怎么实现,推送到指定的客户端
4 楼 hebdan 2012-09-08  
跟DWR的 reverse ajax 有何区别?
3 楼 fffddd 2012-09-08  
安全没有看到有安全相关的验证。随便谁都可以连到你的ws上来?
还有每个账号和每个WS连的关系也没看到。怎么区分发给A用户的信息不会发到B哪里去?
2 楼 85977328 2012-09-08  
xiaozan 写道
请问,这个技术在应用方面可以做哪些功能

WEB开发中,服务器端推送消息
1 楼 xiaozan 2012-09-08  
请问,这个技术在应用方面可以做哪些功能

相关推荐

Global site tag (gtag.js) - Google Analytics