java 7 socket_在Java7与Tomcat8环境下使用WebSocket实现聊天的示例

文中案例在apache-tomcat-8.0.15和jdk1.8.0_25环境下开发,运行。不过标题上是Java7,并不造成影响,代码中没有涉及任何与jdk1.8.x相关的代码。另外之所以要讲清软件版本,一是为了保证案例能够有个明确的实现背景,二是websocket实现tomcat7.x与tomcat8.x有很大差异。

在JavaEE规范集中我们这里主要看Java API for WebSocket(JSR 356)。Websocket-api提供了Java实现Websocket的接口,其中最重要的几个类和注解如下图:

97ec1ccc5c2ac4bdd942fe6964d82f15.png

上图解释:

1.最上面4个注解OnClose,OnError, OnOpen, OnMessage用来标注一个POJO用来处理WebSocket请求的方法;

2.Endpoint和EndpointConfig分别定义了端点和端点相关配置的接口方法;

3.ClientEndpoint和ServerEndpoint分别定义了客户端和服务器端端点的接口方法;

4.Decoder和Encoder分别是解码和编码的接口方法定义;

5.Session是与Endpoint相关的WebSocket Session接口方法定义。

另外还有其它接口,这里作为初步了解Java websocket api仅列出最有必要的一些。

Tomcat8.x提供了JavaEE7的标准实现,其中WebSocket 1.1规范给予实现。在使用其开发的依赖环境是Tomcat8.x JDK7。Tomcat8.x提供了服务器端的实现,客户端实现需要借助其他实现如java_websocket。

Tomcat8.x对WebSocket实现感觉很明朗化了,既然API中定义了WebSocket相关的注解和Session那么Tomcat8.x实现中自然会有相应的处理和实现,下图是简单的关系描述。

4f613956258c8de1c284bd733fef7517.png

上图解释:tomcat的WsSession类实现了Java WebSocket API中的Session接口

PojoEndpointBase以及其子类处理与Endpoint相关的类或注解

EndpointConfig,Endpoint都与Session的实现类之间存在依赖关系

通过了解Java Websocket API和Tomcat8.x对其的实现,认为使用Java WebSocket需要熟悉其中关键类或接口如:Endpoint,EndpointConfig,Client和Server,Encoder和Decoder,Session,MessageHandler。

上面大致介绍了Tomcat8.x对Java Websocket的实现,有关WebSocket规范的了解信息可以参考:

下面是通过代码示例来展示基于WebSocket的实时聊天

1.服务器端实现

package t8j8.examples;

import java.io.IOException;

import java.util.Set;

import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;

import javax.websocket.OnError;

import javax.websocket.OnMessage;

import javax.websocket.OnOpen;

import javax.websocket.Session;

import javax.websocket.server.PathParam;

import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/ws/chat/{nickName}")

public class Chat {

/**

* 连接对象集合

*/

private static final Set connections = new CopyOnWriteArraySet();

private String nickName;

/**

* WebSocket Session

*/

private Session session;

public Chat() {

}

/**

* 打开连接

*

* @param session

* @param nickName

*/

@OnOpen

public void onOpen(Session session,

@PathParam(value = "nickName") String nickName) {

this.session = session;

this.nickName = nickName;

connections.add(this);

String message = String.format("System> %s %s", this.nickName,

" has joined.");

Chat.broadCast(message);

}

/**

* 关闭连接

*/

@OnClose

public void onClose() {

connections.remove(this);

String message = String.format("System> %s, %s", this.nickName,

" has disconnection.");

Chat.broadCast(message);

}

/**

* 接收信息

*

* @param message

* @param nickName

*/

@OnMessage

public void onMessage(String message,

@PathParam(value = "nickName") String nickName) {

Chat.broadCast(nickName + ">" + message);

}

/**

* 错误信息响应

*

* @param throwable

*/

@OnError

public void onError(Throwable throwable) {

System.out.println(throwable.getMessage());

}

/**

* 发送或广播信息

*

* @param message

*/

private static void broadCast(String message) {

for (Chat chat : connections) {

try {

synchronized (chat) {

chat.session.getBasicRemote().sendText(message);

}

} catch (IOException e) {

connections.remove(chat);

try {

chat.session.close();

} catch (IOException e1) {

}

Chat.broadCast(String.format("System> %s %s", chat.nickName,

" has bean disconnection."));

}

}

}

}

说明:

代码中ServerEndpoint注解的value值中有个nickName的参数占位符,该参数占位符称为路径参数,路径参数可以通过方法参数注解(@PathParam)进行设置并且获取;

在Endpoint注解的类中OnClose,OnOpen,OnError注解的方法只有一个,OnMessage注解的方法可以有多个这个容易理解因为WebSocket可能处理的信息有text,binary,textStream等。

2.客户端实现

如果使用Maven的话,可以添加java_websocket jar的依赖。

org.java-websocket

Java-WebSocket

1.3.0

runtime

如果开发Web客户端则可以选择支持WebSocket的浏览器,使用HTML5技术。

下面是使用java_websocket来实现客户端的代码:

package t8j8.examples.client;

import java.net.URI;

import java.net.URISyntaxException;

import java.util.Scanner;

import org.java_websocket.client.WebSocketClient;

import org.java_websocket.drafts.Draft_17;

import org.java_websocket.handshake.ServerHandshake;

public class TestTocatWebSocket {

public static void main(String[] args) throws URISyntaxException {

String url = "ws://localhost:8080/t8j8/ws/chat/" + args[0];

WebSocketClient wc = new WebSocketClient(new URI(url), new Draft_17()) {

@Override

public void onOpen(ServerHandshake handshakedata) {

System.out.println(handshakedata.getHttpStatusMessage());

}

@Override

public void onMessage(String message) {

System.out.println(message);

}

@Override

public void onError(Exception ex) {

}

@Override

public void onClose(int code, String reason, boolean remote) {

}

};

wc.connect();

while (true) {

Scanner scanner = new Scanner(System.in);

String message = scanner.nextLine();

if (message.equals("q")) {

wc.close();

break;

}

scanner.close();

wc.send(message);

}

}

}

说明:

客户端中要说明的是new Draft_17()对象的创建,通过类名可以得知草案的意思。由于Websocket标准迟迟没有发布,因而之前实现都是依据草案进行,而这里的Draft_17对应的WebSocket版本正是:【"Sec-WebSocket-Version", "13" 】可惜,java_websocket包迟迟没有更新内容,名称出现误解人的地方。

3.开始聊天

部署服务器端程序,启动客户端程序(需要添加nickName的参数)。

下面是聊天的截图,分别为Tom和Jack。

6de38aa93a137fcce2dbb088ce073b69.png

65b65a73b85e1b261ce8d78c3f3c7a8e.png

至此,关于使用Tomcat8和JDK7基于WebSocket实现的聊天示例就结束了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值