WebSocket是基于HTML5标准的TCP协议,有点像HTTP,但是它在浏览器和Server之间实现了类似TCP的全双工通信,基于持久连接优于HTTP实现BS方式即时相互通信。在Tomcat7中实现了WebSocket,J2EE7(Servlet3.0)中也实现了WebSocket。
记录一下 Java Web服务端和javascript html客户端实现WebSocket:
1,环境
tomcat7.0.68,
JDK1.7,
WebAPP Server Servlet3.0
js websocket client library:socket.io-1.4.5.js
2,实现服务端
Annotated Endpoints方式:
这种方式配置实现一个ServerEndpoint就行了
package merrick.websocket;
import java.net.InetAddress;
import java.net.URI;
import java.util.Date;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value = "/service1")
public class WS1 {
	@OnOpen
	public void onOpen(Session session,	EndpointConfig conf){<span style="font-family:Arial;">//建立</span>
		
		URI u = session.getRequestURI(); 
		System.out.println(new Date().toString()+", connected: " + session.getRequestURI().toString()+" , info: " );
	}
	
	@OnMessage
	public void onMessage(Session ss, String msg){//收到客户端消息
		try {
			InetAddress adr = InetAddress.getLocalHost();
			String localip = adr.getHostAddress().toString();			
			
			System.out.println(new Date().toString()+", received: " + msg);
			
			ss.getBasicRemote().sendText("["+  new Date().toLocaleString()+"][WS1:_1,"+localip+"] "+msg);
			
			for (int i = 0; i < 4; i++) {
				Thread.currentThread().sleep(5000);				
				ss.getBasicRemote().sendText("["+  new Date().toLocaleString()+"][WS1:_"+ String.valueOf(i+2)  +","+localip+"] "+msg);
			}	
			
			
		} catch (Exception e) {
		
			e.printStackTrace();
		}
	}	
	@OnError
	public void onError(Session session, Throwable error){//
		URI u = session.getRequestURI();
		System.out.println(new Date().toString()+", error: " + session.getRequestURI().toString()+" , info: " + u.getUserInfo());//null info
	}	
	
	@OnClose
	public void onClose(Session ss, CloseReason rz){//连接关闭
		URI u = ss.getRequestURI();
		System.out.println(new Date().toString()+", closed: " + ss.getRequestURI().toString()+" , info: " + u.getUserInfo());//null info
	}
	
}
PROGRAMMATIC EndPoints方式:
这种方式需要实现ServerApplicationConfig接口,并在重写方法中加载ServerEndpointConfig,
package merrick.websocket;
import java.net.InetAddress;
import java.util.Date;
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import org.apache.log4j.Logger;
public class WS2 extends Endpoint  {
	
	private static Logger log = Logger.getLogger(WS2.class);
	@Override
	public void onOpen(final Session ss, EndpointConfig arg1) {
		
		System.out.println(new Date().toString()+", connected: " + ss.getRequestURI().toString()+" , info: " );
		
		
		ss.addMessageHandler(new MessageHandler.Whole<String>() {
					@Override
					public void onMessage(String msg) {
						try {
							InetAddress adr = InetAddress.getLocalHost();
							String localip = adr.getHostAddress().toString();
							String s = new Date().toString()+", received: " + msg;
							log.info(s);
							System.out.println(s);
							
							ss.getBasicRemote().sendText("[WS2: ]"+msg);
							
							for (int i = 0; i < 4; i++) {
								Thread.currentThread().sleep(5000);
								String s2 = "["+  new Date().toLocaleString()+"][WS2:_"+ String.valueOf(i+2)  +","+localip+"] "+msg ;
								
								ss.getBasicRemote().sendText(s2);
								
								log.info("Reply: "+s2);
								
							}
							
							
						} catch (Exception e) {
						
							e.printStackTrace();
						}						
					}					
					
				
				});
		
		
	}
	
	
	@Override
	public void onClose(Session session, CloseReason closeReason) {
		// TODO Auto-generated method stub
		super.onClose(session, closeReason);
	}
	
	@Override
	public void onError(Session session, Throwable throwable) {
		// TODO Auto-generated method stub
		
		System.out.println(throwable.toString());
		
		super.onError(session, throwable);
	}
	
	
}package merrick.websocket;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import org.apache.log4j.Logger;
public class WS2ApplicationConfig implements ServerApplicationConfig {
	
	private static Logger log = Logger.getLogger(WS2ApplicationConfig.class);
	@Override
	public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> arg0) {
		// TODO Auto-generated method stub
		
		log.info("getAnnotatedEndpointClasses");
		
		return arg0;
	}
	@Override
	public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> arg0) {
		// TODO Auto-generated method stub
		
		Set<ServerEndpointConfig> ec = new HashSet<ServerEndpointConfig>();
		ec.add(ServerEndpointConfig.Builder.create(merrick.websocket.WS2.class, "/service2").build());//加载Endpoint服务类
		/**
		 * annotation方式继承Endpoint类无需手动在此ServerApplicationConfig中加载,并且不需要实现ServerApplicationConfig接口
		 * 
		 * */
		
		log.info("getEndpointConfigs");
		
		return ec;
	}
}
3,实现Web客户端
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
	
	<script type="text/javascript" src="socket.io-1.4.5.js"></script>
	<script type="text/javascript" src="jquery-1.9.1.js"></script>
	<script type="text/javascript">
		
	
		$(document).ready(function(){
			
			//等于$(function(){});
		//	var ws = new WebSocket("ws://192.168.245.133:8080/websocketservertest1/service1"); //ws://<ip>:<port>/<projectname>/<endpointpath>
			
			var ws = new WebSocket("ws://localhost:8080/websocketservertest1/service2"); 
			ws.onopen = function(){ws.send("Test!"+new Date().getSeconds()); }; 
			ws.onmessage = function(evt){
				console.log(evt.data);
				
				$("#datadiv").append("<br/>"+evt.data);
				
			//	alert(evt.data);
			//	ws.close();
			}; 
			ws.onclose = function(evt){console.log("WebSocketClosed!");alert("closed");}; 
			ws.onerror = function(evt){console.log("WebSocketError!");alert("error");};
			
			
		});
	
	</script>
	
</head>
<body>
<div id="datadiv"></div>
</body>
</html>4,测试
比如测试/service2的时候在页面上会出现如下定时响应展现:
[WS2: ]Test!15
[2016-10-10 14:49:20][WS2:_2,<ip>] Test!15
[2016-10-10 14:49:25][WS2:_3,<ip>] Test!15
[2016-10-10 14:49:30][WS2:_4,<ip>] Test!15
[2016-10-10 14:49:35][WS2:_5,<ip>] Test!15
 
                   
                   
                   
                   
                            
 
                             
                             本文详细介绍如何使用WebSocket在JavaWeb服务端及JavaScript HTML客户端实现即时双向通信。包括在Tomcat7和J2EE7环境下配置WebSocket,提供两种服务端实现方式(AnnotatedEndpoints与PROGRAMMATIC EndPoints),并给出具体的代码示例。
本文详细介绍如何使用WebSocket在JavaWeb服务端及JavaScript HTML客户端实现即时双向通信。包括在Tomcat7和J2EE7环境下配置WebSocket,提供两种服务端实现方式(AnnotatedEndpoints与PROGRAMMATIC EndPoints),并给出具体的代码示例。
           
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   541
					541
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            