jdk6现实WebSocket

IT黑名单 2016-12-8 16:35:53

伴随着HTML5技术的新起,WebSocket 作为一种浏览器与服务器的核心通信技术,被嵌入到了浏览器的内核中。WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道。
jdk7+已实现webScoket,本文基于jdk6实现webscoket。

1. 服务器端实现(Tomcat)

用Java实现的websocket,在Server端是通过Tomcat内嵌支持的,我们需要开发一个继承WebSocketServlet 的servlet就可以了,与普通的HttpServlet没有太大区别。
1). 环境准备:

2). maven构建一个简单的webapp项目:
3). 编辑pom.xml配置文件,增加tomcat的依赖:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.conan.websocket</groupId>
	<artifactId>websocketServer</artifactId>
	<packaging>war</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>websocketServer Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<dependencies>
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-catalina</artifactId>
			<version>7.0.27</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-coyote</artifactId>
			<version>7.0.39</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<finalName>websocketServer</finalName>
	</build>
</project>
4). 创建DemoServlet,服务器端运行类:

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

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;

public class DemoServlet extends WebSocketServlet {
    private static final long serialVersionUID = -4853540828121130946L;
    private static ArrayList mmiList = new ArrayList();

    @Override
    protected StreamInbound createWebSocketInbound(String str, HttpServletRequest request) {
        return new MyMessageInbound();
    }

    private class MyMessageInbound extends MessageInbound {
        WsOutbound myoutbound;

        @Override
        public void onOpen(WsOutbound outbound) {
            try {
                System.out.println("Open Client.");
                this.myoutbound = outbound;
                mmiList.add(this);
                outbound.writeTextMessage(CharBuffer.wrap("Hello!"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onClose(int status) {
            System.out.println("Close Client.");
            mmiList.remove(this);
        }

        @Override
        public void onTextMessage(CharBuffer cb) throws IOException {
            System.out.println("Accept Message : " + cb);
            for (MyMessageInbound mmib : mmiList) {
                CharBuffer buffer = CharBuffer.wrap(cb);
                mmib.myoutbound.writeTextMessage(buffer);
                mmib.myoutbound.flush();
            }
        }

        @Override
        public void onBinaryMessage(ByteBuffer bb) throws IOException {
        }
    }
}
5). 修改web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<display-name>Archetype Created Web Application</display-name>
	<servlet>
		<servlet-name>wsServlet</servlet-name>
		<servlet-class>org.conan.websocket.DemoServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>wsServlet</servlet-name>
		<url-pattern>/wsServlet</url-pattern>
	</servlet-mapping>
</web-app>
6). 编译,打包,部署,运行

websocket的服务地址:
ws://localhost:8080/websocketServer/wsServlet

2.1 客户端实现(js原生API)

<!DOCTYPE html>
<html>
<head>
	<meta charset=UTF-8>
	<title>js webscoket</title>
	<script>
		var ws = new WebSocket("ws://localhost:8080/websocketServer/wsServlet");
		ws.onopen = function(){};
		ws.onmessage = function(message){
			document.getElementById("chatlog").textContent += message.data + "\n";
		};
		function postToServer(){
			ws.send(document.getElementById("msg").value);
			document.getElementById("msg").value = "";
		}
		function closeConnect(){
			ws.close();
		}
	</script>
</head>
<body>
	<textarea id="chatlog" readonly></textarea><br/>
	<input id="msg" type="text" />
	<button type="submit" id="sendButton" onClick="postToServer()">Send!</button>
	<button type="submit" id="sendButton" onClick="closeConnect()">End</button>
</body>
</html>

2.2 客户端实现(Java-WebSocket)

maven依赖

<dependency>
	<groupId>org.java-websocket</groupId>
	<artifactId>Java-WebSocket</artifactId>
	<version>1.3.0</version>
</dependency>

ChatClient.java

import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.net.URI;
import java.net.URISyntaxException;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import org.java_websocket.WebSocketImpl;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_10;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.drafts.Draft_75;
import org.java_websocket.drafts.Draft_76;
import org.java_websocket.handshake.ServerHandshake;

public class ChatClient extends JFrame implements ActionListener {
	private static final long serialVersionUID = -6056260699202978657L;

	private final JTextField uriField;
	private final JButton connect;
	private final JButton close;
	private final JTextArea ta;
	private final JTextField chatField;
	private final JComboBox draft;
	private WebSocketClient cc;

	public ChatClient(String defaultlocation) {
		super("WebSocket Chat Client");
		Container c = getContentPane();
		GridLayout layout = new GridLayout();
		layout.setColumns(1);
		layout.setRows(6);
		c.setLayout(layout);

		Draft[] drafts = { new Draft_17(), new Draft_10(), new Draft_76(),
				new Draft_75() };
		draft = new JComboBox(drafts);
		c.add(draft);

		uriField = new JTextField();
		uriField.setText(defaultlocation);
		c.add(uriField);

		connect = new JButton("Connect");
		connect.addActionListener(this);
		c.add(connect);

		close = new JButton("Close");
		close.addActionListener(this);
		close.setEnabled(false);
		c.add(close);

		JScrollPane scroll = new JScrollPane();
		ta = new JTextArea();
		scroll.setViewportView(ta);
		c.add(scroll);

		chatField = new JTextField();
		chatField.setText("");
		chatField.addActionListener(this);
		c.add(chatField);

		java.awt.Dimension d = new java.awt.Dimension(300, 400);
		setPreferredSize(d);
		setSize(d);
		addWindowListener(new java.awt.event.WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if (cc != null) {
					cc.close();
				}
				dispose();
			}
		});
		setLocationRelativeTo(null);
		setVisible(true);
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == chatField) {
			if (cc != null) {
				cc.send(chatField.getText());
				chatField.setText("");
				chatField.requestFocus();
			}

		} else if (e.getSource() == connect) {
			try {
				cc = new WebSocketClient(new URI(uriField.getText()),
						(Draft) draft.getSelectedItem()) {

					@Override
					public void onMessage(String message) {
						ta.append("got: " + message + "\n");
						ta.setCaretPosition(ta.getDocument().getLength());
					}

					@Override
					public void onOpen(ServerHandshake handshake) {
						ta.append("You are connected to ChatServer: "
								+ getURI() + "\n");
						ta.setCaretPosition(ta.getDocument().getLength());
					}

					@Override
					public void onClose(int code, String reason, boolean remote) {
						ta.append("You have been disconnected from: "
								+ getURI() + "; Code: " + code + " " + reason
								+ "\n");
						ta.setCaretPosition(ta.getDocument().getLength());
						connect.setEnabled(true);
						uriField.setEditable(true);
						draft.setEditable(true);
						close.setEnabled(false);
					}

					@Override
					public void onError(Exception ex) {
						ta.append("Exception occured ...\n" + ex + "\n");
						ta.setCaretPosition(ta.getDocument().getLength());
						ex.printStackTrace();
						connect.setEnabled(true);
						uriField.setEditable(true);
						draft.setEditable(true);
						close.setEnabled(false);
					}
				};

				close.setEnabled(true);
				connect.setEnabled(false);
				uriField.setEditable(false);
				draft.setEditable(false);
				cc.connect();
			} catch (URISyntaxException ex) {
				ta.append(uriField.getText()
						+ " is not a valid WebSocket URI\n");
			}
		} else if (e.getSource() == close) {
			cc.close();
		}
	}

	public static void main(String[] args) {
		WebSocketImpl.DEBUG = true;
		String location;
		if (args.length != 0) {
			location = args[0];
			System.out.println("Default server url specified: \'" + location
					+ "\'");
		} else {
			location = "ws://localhost:8887";
			System.out
					.println("Default server url not specified: defaulting to \'"
							+ location + "\'");
		}
		new ChatClient(location);
	}
}


转载请注明来源【IT黑名单

本文链接:http://blog.itblacklist.cn/20161208/8437.html

© Copyright 2016 IT黑名单 Inc.All Rights Reserved. 豫ICP备15018592号-2