web消息推送技术

最近在做一个web项目,有个需求是服务器向客户端发送数据,一般来讲,web是请求响应方式是无法做到服务端直接给客户端发送数据的。第一想到的是轮询方法,让客户端不断刷新访问服务器。

这种方法缺点是刷新频率不好控制,设置高了会给服务器造成很大负担,相反,消息得不到及时更新。


目前,我找到两种较优的方法。

1 . comet 技术 ——基于长连接的技术

在传统轮询方法上做的改进。

客户端和服务器保持一个长连接,当服务器向客服端发送消息,才响应数据。这种解决方案,可以说是无奈之举。

参考DWR框架

2. websocket技术 ——基于双向传输技术

html5就提供了这种技术的支持。

我就尝试了第二种方案,结合网友代码在tomcat7.0上做的例子,仅供参考!


index.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>







Insert title here


   
Message
Name
js/jsocket.js

var username = window.prompt("输入你的名字:");

document.write("Welcome

"+username+"

"); if (!window.WebSocket && window.MozWebSocket) window.WebSocket=window.MozWebSocket; if (!window.WebSocket) alert("No Support "); var ws; $(document).ready(function(){ $("#sendbutton").attr("disabled", false); $("#sendbutton").click(sendMessage); startWebSocket(); }) function sendMessage() { var othername=$("#othername").val(); var msg="MSG\t"+username+"_"+othername+"_"+$("#message").val(); send(msg); } function send(data) { console.log("Send:"+data); ws.send(data); } function startWebSocket() { ws = new WebSocket("ws://" + location.host + "/web_socket/websocket/test"); ws.onopen = function(){ console.log("success open"); $("#sendbutton").attr("disabled", false); }; ws.onmessage = function(event) { console.log("RECEIVE:"+event.data); handleData(event.data); }; ws.onclose = function(event) { console.log("Client notified socket has closed",event); }; } function handleData(data) { var vals=data.split("\t"); var msgType=vals[0]; switch(msgType) { case "NAME": var msg=vals[1]; var mes="NAME"+"\t"+msg+"_"+ username; send(mes); break; case "MSG": var val2s=vals[1].split("_"); var from=val2s[0]; var message=val2s[2]; alert(from+":"+message); break; default: break; } }

web.xml




  web_socket
  
    index.html
    index.htm
    index.jsp
    default.html
    default.htm
    default.jsp
  
  
    
      wsSnake  
      cn.eaglestart.websocket.MyWebSocketServlet  
      
      
      wsSnake  
      /websocket/test  
      
    
    

MyMessageInbound.java

package cn.eaglestart.websocket;

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

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

public class MyMessageInbound  extends MessageInbound{

	private String username;
	private Set users = new CopyOnWriteArraySet();
	
	 public static int USERNUMBER = 1;

	
	public MyMessageInbound(Set users) {
		super();
		this.users = users;
	}

	@Override
	protected void onBinaryMessage(ByteBuffer arg0) throws IOException {
		// TODO Auto-generated method stub
		
	}

	@Override
	protected void onTextMessage(CharBuffer arg0) throws IOException {
		String data = arg0.toString();
		 System.out.println("data:" + data);
         String[] val1 = data.split("\\t");
         
         if(val1[0].equals("NAME"))
         {
             String[] val2=val1[1].split("_");
             for(MyMessageInbound user:users){
                 if (user.username.equals(val2[0])){
                     user.username=val2[1];
                 }
             }
         }
         else if(val1[0].equals("MSG"))
         {
             String[] val2=val1[1].split("_");
             for(MyMessageInbound user:users){
                 if (user.username.equals(val2[1])){
                     try {
                         CharBuffer temp=CharBuffer.wrap(data);
                         user.getWsOutbound().writeTextMessage(temp);
                     } catch (IOException e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
                     }
                 }
             }        
         }
         else
         {
             System.out.println("ERROR");
         }

     }

	@Override
	protected void onOpen(WsOutbound outbound) {
		// TODO Auto-generated method stub
		  // this.connection=connection;
		
        this.username = "#" + String.valueOf(USERNUMBER);
        System.out.println(username);
        USERNUMBER++;
        try {
            String message = "NAME" + "\t" + this.username;
            CharBuffer buffer = CharBuffer.wrap(message);
            this.getWsOutbound().writeTextMessage(buffer);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        users.add(this);

	}
	
	 public void onMessage(String data) {
		 System.out.println("data:" + data);
         String[] val1 = data.split("\\t");
         
         if(val1[0].equals("NAME"))
         {
             String[] val2=val1[1].split("_");
             for(MyMessageInbound user:users){
                 if (user.username.equals(val2[0])){
                     user.username=val2[1];
                 }
             }
         }
         else if(val1[0].equals("MSG"))
         {
             String[] val2=val1[1].split("_");
             for(MyMessageInbound user:users){
                 if (user.username.equals(val2[1])){
                     try {
                         CharBuffer temp=CharBuffer.wrap(data);
                         user.getWsOutbound().writeTextMessage(temp);
                     } catch (IOException e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
                     }
                 }
             }        
         }
         else
         {
             System.out.println("ERROR");
         }

     }
	 @Override
     protected void onClose(int status) {
         users.remove(this);

     }


	
	

}

MyWebSocketServlet.java

package cn.eaglestart.websocket;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.servlet.http.HttpServletRequest;

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

public class MyWebSocketServlet  extends WebSocketServlet{

	
	 public final Set users = new CopyOnWriteArraySet();

	    public static int USERNUMBER = 1;

	@Override
	protected StreamInbound createWebSocketInbound(String arg0,
			HttpServletRequest arg1) {
		System.out.println("=====init====");
		// TODO Auto-generated method stub
		return new MyMessageInbound(users);
	}

}

参考代码链接如下
html5利用websocket完成的推送功能


你可能感兴趣的:(websocket,comet,tomcat,消息推送)