Jetty 8.1.1 Websocket客户端握手 [英] Jetty 8.1.1 Websocket client handshake

查看:140
本文介绍了Jetty 8.1.1 Websocket客户端握手的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Jetty 8.1.1 Websocket客户端api.
我需要用("Sec-WebSocket-Protocol", "xsCrossfire")("Authorization", "Basic TLVWQMZqRr2hasYnZoI=")

I'm using Jetty 8.1.1 Websocket client api.
I need to update the headers with ("Sec-WebSocket-Protocol", "xsCrossfire") and ("Authorization", "Basic TLVWQMZqRr2hasYnZoI=")

WebSocketClientFactory factory = new WebSocketClientFactory();
factory.start();
client = factory.newWebSocketClient();
client.getCookies().put("Sec-WebSocket-Protocol", "xsCrossfire");
client.getCookies().put("Authorization", "Basic TLVWQMZqRr2hasYnZoI=");
Future<Connection> conn = client.open(uri, (WebSocket) this);
System.out.printf("Connecting to : %s%n", uri);

请求外观:

Host: iltlvl262:8000\r\n
Upgrade: websocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Version: 13\r\n
Sec-WebSocket-Key: FHKTsICO2vqGCxXVwLkH4Q==\r\n
Cookie: Sec-WebSocket-Protocol=xsCrossfire\r\n
Cookie: Authorization="Basic TLVWQMZqRr2hasYnZoI="\r\n

预期的请求:

Host: iltlvl262:8000\r\n
Upgrade: websocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Version: 13\r\n
Sec-WebSocket-Key: FHKTsICO2vqGCxXVwLkH4Q==\r\n
Sec-WebSocket-Protocol: xsCrossfire\r\n
Authorization: "Basic TLVWQMZqRr2hasYnZoI="\r\n

如何在8.1.1版中正确实现握手?

how do I implement handshake in version 8.1.1 correctly?

推荐答案

一些好消息和一些坏消息.

Some good news and some bad news.

首先,好消息:

要设置Sec-WebSocket-Protocol标头,请使用以下内容.

To set the Sec-WebSocket-Protocol header use the following.

client.setProtocol("xsCrossfire");

在使用client.open()

接下来,是坏消息:

使用Jetty 8.x,您不能设置任意的非websocket标头.这是由于WebSocket的早期实验草案是如何编写的.根本不允许您按照早期的规范草案设置任意标题,因此,在Jetty 8.x时代的实现只是不允许这样做.

With Jetty 8.x you cannot set arbitrary non-websocket headers. This was due to how early experimental drafts of WebSocket were written. You simply were not allowed to set arbitrary headers per the early draft specs, so the implementation back in the Jetty 8.x days just didn't allow it.

但是,随着 RFC6455 (WebSocket官方规范)的定稿,所有这些更改都被汇总到了Jetty 9.x代码库.符合100% RFC6455 . (注意:Jetty 8在服务器端100%兼容RFC6455.Jetty8在服务器和客户端使用的RFC6455协议上也100%兼容.但是,Jetty 8仅在客户端部分兼容,从功能和API的角度来看.)

However, with the finalization of RFC6455 (the official WebSocket spec) things changed, all of those changes were rolled into the Jetty 9.x codebase. Which is 100% RFC6455 compliant. (Note: Jetty 8 is 100% compliant to RFC6455 on the server side. Jetty 8 is also 100% compatible on the RFC6455 protocol use for both server and client. However, Jetty 8 is only partially compliant on the client side, from a features and API point of view.)

Jetty 7和Jetty 8的决定是保留旧的实验性草稿,供那些仍在使用它们的早期采用者和旧版浏览器(Safari 5.x)使用​​.这一决定使我们无法允许在旧的实验草案中明确禁止的行为.

The decision with Jetty 7 and Jetty 8 was made to keep the old experimental drafts around for those early adopters and old browsers (Safari 5.x) that still used them. This decision prevented us from allowing behaviors that are specifically prevented in the old experimental drafts.

从Jetty 9.x开始,删除了所有websocket的实验性草案,仅保留了 RFC6455 的支持,码头开辟了以前不允许的更多功能.这包括WebSocketClient上的任意标头.

Starting with Jetty 9.x all old experimental drafts of websocket were dropped, leaving only RFC6455 to support, which allowed Jetty to open up more features that were previously disallowed. This includes arbitrary headers on the WebSocketClient.

Jetty 9.1 WebSocket客户端示例

import java.io.IOException;
import java.net.URI;
import java.util.concurrent.Future;

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;

public class ExampleClient
{
    public static class ExampleSocket extends WebSocketAdapter
    {
        @Override
        public void onWebSocketText(String message)
        {
            try
            {
                // echo the message
                getRemote().sendString(message);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args)
    {
        try
        {
            new ExampleClient().demo();
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }

    public void demo() throws Exception
    {
        WebSocketClient client = new WebSocketClient();
        try
        {
            client.start();
            ClientUpgradeRequest request = new ClientUpgradeRequest();
            request.setSubProtocols("xsCrossfire");
            request.setHeader("Authorization","Basic TLVWQMZqRr2hasYnZoI=");

            URI wsUri = URI.create("ws://iltlvl262:8000/echo");

            ExampleSocket socket = new ExampleSocket();
            Future<Session> future = client.connect(socket,wsUri,request);

            future.get(); // wait for connect

            socket.getRemote().sendString("hello"); // send message
        }
        finally
        {
            client.stop();
        }
    }
}

还要注意,从Jetty 9.1开始,甚至 javax.websocket (JSR-356)API完全受支持.

Also note, that starting with Jetty 9.1, even the javax.websocket (JSR-356) API is fully supported.

在Jetty 9.1上使用javax.websocket的相同示例

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.websocket.ClientEndpoint;
import javax.websocket.ContainerProvider;
import javax.websocket.OnMessage;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

public class ExampleClient
{
    @ClientEndpoint(subprotocols = { "xsCrossfire" }, 
                    configurator = ExampleClient.Configurator.class)
    public static class ExampleSocket
    {
        @OnMessage
        public String onMessage(String msg)
        {
            return msg; // echo
        }
    }

    public static class Configurator 
           extends javax.websocket.ClientEndpointConfig.Configurator
    {
        @Override
        public void beforeRequest(Map<String, List<String>> headers)
        {
            List<String> authvalues = new ArrayList<>();
            authvalues.add("Basic TLVWQMZqRr2hasYnZoI=");
            headers.put("Authorization", authvalues);
            super.beforeRequest(headers);
        }
    }

    public static void main(String[] args)
    {
        try
        {
            new ExampleClient().demo();
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }

    public void demo() throws Exception
    {
        WebSocketContainer client = ContainerProvider.getWebSocketContainer();

        ExampleSocket socket = new ExampleSocket();
        URI wsUri = URI.create("ws://iltlvl262:8000/echo");

        Session session = client.connectToServer(socket,wsUri);
        session.getAsyncRemote().sendText("Hello");
    }
}

这篇关于Jetty 8.1.1 Websocket客户端握手的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆