一些好消息和一些坏消息.
一,好消息:
要设置Sec-WebSocket-Protocol标头,请使用以下命令.
client.setProtocol("xsCrossfire");
在使用client.open()之前
接下来,坏消息:
使用Jetty 8.x,您无法设置任意非websocket标头.这是由于WebSocket的早期实验草稿是如何编写的.根据早期草案规范,您根本不允许设置任意标头,因此Jetty 8.x天后的实现只是不允许它.
但是,随着RFC6455(官方WebSocket规范)的最终确定,事情发生了变化,所有这些变化都进入了Jetty 9.x代码库.符合100%RFC6455标准. (注意:Jetty 8在服务器端100%兼容RFC6455.Jetty 8在服务器和客户端的RFC6455协议上也是100%兼容的.但是,Jetty 8在客户端只是部分兼容,从功能和API的观点.)
Jetty 7和Jetty 8的决定是为那些仍在使用它们的早期采用者和旧浏览器(Safari 5.x)保留旧的实验草案.这一决定阻止我们允许在旧的实验草案中特别阻止的行为.
从Jetty 9.x开始,所有旧的websocket实验草稿都被删除,只留下RFC6455支持,这使得Jetty可以打开更多以前不允许的功能.这包括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 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.
在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> headers)
{
List 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");
}
}