Fork me on GitHub

WebSockets

Introduction

WebSocket协议支持客户端和服务器之间的双向通信. 该协议包括一个开放的握手,随后是基于TCP分层的基本消息框架. 该技术的目标是为基于浏览器的应用程序提供一种机制,该应用程序需要与不依赖于打开多个HTTP连接的服务器进行双向通信.

Ninja v6.2.0 +包括对WebSocket的全面支持. Ninja在设计为与标准Java WebSocket标准(JSR-356)一起使用时,除了JSR-356之外,还包括许多有用的功能,从而使Web套接字的使用更加简单.

Setup

确保您正在运行Ninja 6.2.0+. Ninja WebSockets将在Jetty独立版本中开箱即用. 如果将您的Ninja应用程序作为WAR运行. Ninja WebSockets也可以在任何支持JSR-356的servlet容器中使用. Ninja的实现已针对Jetty 9.3.15 +,Tomcat 7.0.81+和Wildfly 10+进行了测试.

如果在servlet容器中作为WAR运行,则需要交换GuiceFilter并使用ninja.servlet.NinjaServletFilter . 或者,您可以通过其ServletContainerInitializer支持简单地使用Ninja的自动Servlet配置,甚至可以省略web.xml .

Add a WebSocket route

所有WebSocket端点都将在Ninja的路由器中进行配置. WS的一种新的伪HTTP方法表示路由用于WebSocket. 处理它的控制器方法将能够接受/拒绝握手并协商协议和扩展. 如果您曾经使用过标准的JSR-356 WebSocket,您将欣赏Ninja的实现有多么容易.

public class Routes implements ApplicationRoutes {
    @Override
    public void init(Router router) {

        router.WS().route("/echo").with(EchoWebSocket::handshake);
        router.WS().route("/chats/{id}").with(ChatWebSocket::handshake);

    }
}

请注意,根据所提供的基础Ninja WebSocket支持的不同,您会受到可以使用的URI的限制. 如果使用标准JSR-356 WebSockets(几乎总是这样),则可以使用简单的路径参数,例如/ chat / {id} ,而不能使用正则表达式,例如/ chat / {id:.*} .

您在路由中指定的握手方法的声明类将成为WebSocket端点. 如果您使用的是JSR-356 WebSockets,则意味着您的控制器类将需要实现javax.websocket.Endpoint接口. 有关完整的示例,请参见下面的代码.

Web socket controller/endpoint

您将要确保不要将WebSocket类标记为@Singleton . 除非您知道自己在做什么,否则最好为每个创建的WebSocket会话创建一个新实例.

您的控制器/端点将使用Guice创建-因此在实例化端点时将使用@Inject注释.

WebSocket handshake

Java的JSR-356标准的问题之一是,您对初始握手请求的控制很少,并且对客户端发送的HTTP标头的访问也很少. 这种设计缺陷将使得无法使用Ninja的会话或上下文.

Ninja通过使用两步过程来完成握手,从而使用JSR-356修复了此设计缺陷. 当客户端发起WebSocket请求时,Ninja将检测到该尝试,实例化您的WebSocket端点,并调用您的握手控制器方法(就像任何标准的HTTP GET请求一样). 然后,可以在建立WebSocket会话后接受/拒绝握手请求或保存以后要访问的任何变量.

public class ChatWebSocket extends Endpoint implements MessageHandler.Whole<String> {
    
    public Result handshake(Context context, WebSocketHandshake handshake) {
        // negotiate the protocol (not always used by clients)
        handshake.selectProtocol("chat");

        // process handshake, save whatever you need, tell ninja to proceed
        // or return a failure result to reject the request
        return Results.webSocketContinue();
    }

    @Override
    public void onOpen(Session session, EndpointConfig config) {
        // jsr-356 stuff here...
    }

如果您的握手方法返回的状态码为101,那么Ninja将让基础HTTP容器继续将连接升级到WebSocket. 如果升级成功,Ninja保证为您的握手创建的实例将与将接收onOpen事件的实例相同.

WebSocket session

握手完成并建立WebSocket会话后,您将像其他任何JSR-356实现一样处理处理. 例如,Internet上有许多资源.


by  ICOPY.SITE