手记

Tomcat实现Web Socket


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
    }
}



作者:我是杨正
链接:https://www.jianshu.com/p/00e9f73d5d22


0人推荐
随时随地看视频
慕课网APP