Tomcat7 Websocket入门贴

传统的J2EE程序,浏览器端并没有推送机制,如果浏览器想要实时获取服务端的最新信息,那么必须通过轮询的方式。很显然轮询方式既浪费http带宽,又难以保证实时性。手机端的消息推送很方便,很好用。比如百度提供的百度云推送方案,google的GCM推送,apple的apns推送,基于这些推送服务,我们可以很容易构建出手机端的实时应用。websocket的引入,就是为了让浏览器也能像手机一样,被动接受服务端的推送信息。


HTML5中引入了WebSocket,浏览器的编码是很容易的。我写了一个简单的模拟登录、登出、发消息的界面:


<head>
<script src="jquery-1.11.1.min.js"></script>
<script>
$(function(){
	
	// 浏览器上的websocket对象,用来和服务端通信.
	var socket = null;
	
	$("#login").click(function(){
		var userName = $("#userName").val();
		if($.trim(userName) == "")
		{
			return;
		}
		
		// 创建websocket对象
		socket = new WebSocket('ws://localhost:8080/websocket/chat?userName='+userName);
		registerEvent();
	});
	
	$("#logout").click(function(){
		socket.close();
	});
	
	$("#send").click(function(){
		socket.send($("#message").val());
	});

	function registerEvent()
	{
		socket.onopen = function(event) { 
			$("#messagePanel").append("<div>websocket open successfully.</div>");
		}
		
		socket.onmessage = function(event) { 
			$("#messagePanel").append("<div>msg="+event.data+"</div>");
		}; 
	  
		socket.onclose = function(event) { 
			$("#messagePanel").append("<div>websocket close successfully.</div>");
		};			
	}
	

});


</script>
<style>
	.card{
		margin:20px;
	}
</style>
</head>
<body>
	<div class="card">
		userName:<input id="userName" value="" placeholder="input your name"/>
		<button id="login">login</button>
		<button id="logout">logout</button>
	</div>
	<div class="card">
		message:<input id="message" value="" placeholder="input your message"/>
		<button id="send">send</button>
	</div>
	
	<div class="card" id="messagePanel">
		
	</div>
</body>


可以看到客户端的编程是很容易的,我们主要看下服务端的编程。

package aty.net;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

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;

@WebServlet(name = "chat", urlPatterns = "/chat")
public class ChatWebSocket extends WebSocketServlet {

	private static final String GUEST_PREFIX = "Guest";

	private final Set<ChatMessageInbound> connections = new CopyOnWriteArraySet<ChatMessageInbound>();
	
	@Override
	protected StreamInbound createWebSocketInbound(String subProtocol,
			HttpServletRequest request) {
		return new ChatMessageInbound(request.getParameter("userName"));
	}

	private final class ChatMessageInbound extends MessageInbound {

		private final String nickname;

		private ChatMessageInbound(String name) {
			this.nickname = name;
		}

		@Override
		protected void onOpen(WsOutbound outbound) {
			connections.add(this);
			
			System.out.println(nickname + "has joined.");
			broadcast(nickname + " has joined.");
		}

		@Override
		protected void onClose(int status) {
			connections.remove(this);
			System.out.println(nickname + "has leaved.");
			broadcast(nickname + " has leaved.");
		}
		
		@Override
		protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
			
		}

		@Override
		protected void onTextMessage(CharBuffer buffer) throws IOException {

			System.out.println(nickname + " say:" + buffer.toString());
			broadcast(nickname + " say:" + buffer.toString());
		}

		private void broadcast(String message) {
			for (ChatMessageInbound connection : connections) {
				try {
					CharBuffer buffer = CharBuffer.wrap(message);
					connection.getWsOutbound().writeTextMessage(buffer);
				} catch (IOException ignore) {
				}
			}
		}
	}
}
可以看到我们使用了WebSocketServlet接受请求,使用MessageInbound来处理真正的websocket连接。


为了保证上面的java代码编译通过,需要引入catalina.jar、servlet-api.jar、tomcat-coyote.jar。需要特别注意:这3个包只是编译需要,实际运行的时候不能将这3个jar放到我们的war包中。因为tomcat7运行环境,自带的就有这些jar。我实验过:如果将这些jar包放到我们自己war包下,会导致创建websocket失败



接下来我们可以在tomcat7下运行上面的代码,打开1个浏览器客户端。



现在我们打开第二个客户端,操作步骤同第一个客户端一样。



现在我们看下第一个客户端:


很明显:第一个客户端能够收到消息,这就是推送,非常方便。基于websocket推送,我们能够更好、更容易地构建监控等实时应用的程序。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值