Tomcat实现Web Socket
2018-10-14 本文已影响1人
我是杨正
原文链接:https://www.dubby.cn/detail.html?id=9103
1、依赖
本文使用的是Tomcat9
项目结构也是最基本的servlet的项目结构:
image代码地址:https://github.com/dubby1994/tomcat-web-socket-study
其实啥依赖都不需要,但是需要几个api,这些在Tomcat里都已经提供了,但是代码里还是需要提供一下,不然编译报错:
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
2、配置
ExamplesConfig.java
package cn.dubby.tomcat.study.config;
import cn.dubby.tomcat.study.ws.EchoEndpoint;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import java.util.HashSet;
import java.util.Set;
public class ExamplesConfig implements ServerApplicationConfig {
@Override
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> scanned) {
Set<ServerEndpointConfig> result = new HashSet<>();
if (scanned.contains(EchoEndpoint.class)) {
result.add(ServerEndpointConfig.Builder.create(EchoEndpoint.class, "/websocket").build());
}
return result;
}
@Override
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
Set<Class<?>> results = new HashSet<>();
for (Class<?> clazz : scanned) {
if (clazz.getPackage().getName().contains("ws")) {
results.add(clazz);
}
}
return results;
}
}
其中getEndpointConfigs
是配置所有继承Endpoint
的类,而getAnnotatedEndpointClasses
是配置所有被@ServerEndpoint
修饰的类。
3、继承Endpoint
public class EchoEndpoint extends Endpoint {
private static final AtomicLong count = new AtomicLong();
@Override
public void onOpen(Session session, EndpointConfig endpointConfig) {
System.out.println("在线人数:" + count.incrementAndGet());
session.addMessageHandler(new EchoMessageHandlerText(session));
}
@Override
public void onClose(Session session, CloseReason closeReason) {
System.out.println("在线人数:" + count.decrementAndGet());
}
private static class EchoMessageHandlerText implements MessageHandler.Partial<String> {
private final Session session;
private EchoMessageHandlerText(Session session) {
this.session = session;
}
@Override
public void onMessage(String message, boolean last) {
if (session == null)
return;
System.out.println(session.getId() + "\t" + message);
try {
session.getBasicRemote().sendText(message, last);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4、使用注解
@ServerEndpoint("/websocket2")
public class EchoEndpoint2 {
private static final AtomicLong count = new AtomicLong();
@OnOpen
public void open(Session session) {
System.out.println("在线人数:" + count.incrementAndGet());
try {
session.getBasicRemote().sendText("welcome");
} catch (IOException e) {
e.printStackTrace();
}
}
@OnClose
public void close(Session session) {
System.out.println("在线人数:" + count.decrementAndGet());
}
@OnMessage
public void echoTextMessage(Session session, String message) {
System.out.println(session.getId() + "\t" + message);
try {
if (session.isOpen()) {
session.getBasicRemote().sendText(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@OnMessage
public void echoBinaryMessage(Session session, ByteBuffer bb) {
System.out.println(session.getId() + "\t" + bb.toString());
try {
if (session.isOpen()) {
session.getBasicRemote().sendBinary(bb);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@OnMessage
public void echoPongMessage(PongMessage pm) {
//pass
}
}
例子就不给了,和昨天的几乎是一样的,你可以直接用昨天的那个html来测试今天的。