WebSocketはtomcat 7にあります.0.29での応用

7522 ワード

1、WebSocketとは
 
 
WebSocketは、HTML 5が提供し始めたブラウザとサーバ間でフルデュプレクス通信を行うネットワーク技術です.
WebSocket APIでは、ブラウザとサーバが握手するだけで、ブラウザとサーバの間に高速チャネルが形成されます.両者の間で直接データを互いに転送することができる.
 
 
2、開発環境
eclipse-jee-indigo-SR2-win32
apache-tomcat-7.0.29
tomcatは7.0.2からWebSocketをサポートしており、現在の最新版(2012.8.17現在)は7.0.29であり、7.0.2に比べて改善されている.
3、開発手順
3.1 Dynamic Webプロジェクトの作成、Target runtime apache-tomcat-7.0.29の選択
3.2 WebSocketの要求に応答するservletを作成する
 
package websocket;

import javax.servlet.http.HttpServletRequest;

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

/**
 * 
 * @author allan_he
 *  Servlet   WebSocketServlet,  createWebSocketInbound  
 */
public class MyWebSocketServlet extends WebSocketServlet {

	private static final long serialVersionUID = 7648892814938958971L;
	
	/**
	 *   tomcat7.0.27   
	@Override
	protected StreamInbound createWebSocketInbound(String arg0) {
		System.out.println("#########################################");
		return new MyMessageInbound();
	}
	*/
	
	/**
	 *   tomcat7.0.29   ,  7.0.27   ,Tomcat   createWebSocketInbound     ,
	 *      HttpServletRequest  ,         request             
	 *         MyMessageInbound,    MessageInbound
	 * MessageInbound StreamInbound   
	 * */
	@Override
	protected StreamInbound createWebSocketInbound(String arg0,
			HttpServletRequest arg1) {
		System.out.println("#########################################");
		return new MyMessageInbound();
	}

}

3.3 WebSocketタスクごとに処理するMessageInboundのサブクラスを作成する
package websocket;

import init.InitServlet;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.WsOutbound;
/**
 * @author allan_he
 *       WebSocket  
 *            ,  onOpen onClose     
 */
public class MyMessageInbound extends MessageInbound {

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

	//          
	@Override
	protected void onTextMessage(CharBuffer msg) throws IOException {
		for (MessageInbound messageInbound : InitServlet.getSocketList()) {
			CharBuffer buffer = CharBuffer.wrap(msg);
			// getWsOutbound       WsOutbound,           ,      nio CharBuffer
			WsOutbound outbound = messageInbound.getWsOutbound();
			outbound.writeTextMessage(buffer);
			outbound.flush();
		}
	}

	/**
	 *  WebSocket    ,  status    org.apache.catalina.websocket.Constants        ,
	 *              Tomcat   
	 */
	@Override
	protected void onClose(int status) {
		InitServlet.getSocketList().remove(this);
		super.onClose(status);
	}
	
	// WebSocket    ,    ,WsOutbound          
	@Override
	protected void onOpen(WsOutbound outbound) {
		super.onOpen(outbound);
		InitServlet.getSocketList().add(this);
	}
		

}

 
3.4初期化用servletの作成
package init;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.catalina.websocket.MessageInbound;

public class InitServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5218126862760826639L;
	
	private static List<MessageInbound> socketList;  
    
    public void init(ServletConfig config) throws ServletException {  
        InitServlet.socketList = new ArrayList<MessageInbound>();  
        super.init(config);  
        System.out.println("Server start============");  
    }  
      
    public static synchronized List<MessageInbound> getSocketList() {  
        return InitServlet.socketList;  
    }  

}

 
3.5 webを構成する.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>wsoc</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
  	<servlet-name>mywebsocket</servlet-name>
  	<servlet-class>websocket.MyWebSocketServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mywebsocket</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>
  
  <servlet>
  	<servlet-name>initServlet</servlet-name>
  	<servlet-class>init.InitServlet</servlet-class>
  	<load-on-startup>1</load-on-startup>
  </servlet>
</web-app>

 
3.6テストページを作成し、パスが正しくなければ接続できないことに注意する.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Index</title>
<script type="text/javascript">
var ws = null;
function startWebSocket() {
	if ('WebSocket' in window){
		ws = new WebSocket("ws://localhost:8080/html5WebSocket/mywebsocket.do");
	}
		
	else if ('MozWebSocket' in window)
		ws = new MozWebSocket("ws://localhost:8080/html5WebSocket/mywebsocket.do");
	else
		alert("not support");
	
	
	ws.onmessage = function(evt) {
		//alert(evt.data);
		document.getElementById('chatMessage').innerHTML=evt.data;
	};
	
	ws.onclose = function(evt) {
		alert("close");
	};
	
	ws.onopen = function(evt) {
		alert("open");
	};
}

function sendMsg() {
	ws.send(document.getElementById('writeMsg').value);
}
</script>
</head>
<body onload="startWebSocket();">
<input type="text" id="writeMsg"></input>
<input type="button" value="send" onclick="sendMsg()"></input>
<div id="chatMessage"></div>
</body>
</html>