聊天-websocket

该篇博客探讨了WebSocket连接在应用启动时开启但在手机号验证成功后才能真正建立的问题。记录了403Forbidden和500ServerError错误,指出这些问题可能与服务器配置、认证失败及心跳包机制有关。同时,提到了nginx服务器需要支持wss并配置路由模块,以及WebSocket连接成功后的认证过程。
摘要由CSDN通过智能技术生成

websocket

WebSocketConnection 是在application#oncreate的时候就开启了,但是只有在手机号验证完成登录成功后才能连接成功。

2021-04-09 15:19:38.742 5902-6373/org.thoughtcrime.securesms I/WebSocketConnection: connect()
2021-04-09 15:19:38.758 5902-6373/org.thoughtcrime.securesms I/ApplicationDependencyPr: onConnecting()
2021-04-09 15:19:39.414 5902-6394/org.thoughtcrime.securesms W/WebSocketConnection: onFailure()
    java.net.ProtocolException: Expected HTTP 101 response but was '403 Forbidden'
        at okhttp3.internal.ws.RealWebSocket.checkResponse(RealWebSocket.java:229)
        at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:196)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)
2021-04-09 15:19:39.414 5902-6394/org.thoughtcrime.securesms W/ApplicationDependencyPr: onAuthenticationFailure()
2021-04-09 15:19:39.414 5902-6394/org.thoughtcrime.securesms D/EventBus: No subscribers registered for event class org.thoughtcrime.securesms.events.ReminderUpdateEvent
2021-04-09 15:19:39.414 5902-6394/org.thoughtcrime.securesms D/EventBus: No subscribers registered for event class org.greenrobot.eventbus.NoSubscriberEvent
2021-04-09 15:19:39.414 5902-6394/org.thoughtcrime.securesms I/WebSocketConnection: onClose()
2021-04-09 15:19:39.414 5902-6394/org.thoughtcrime.securesms W/ApplicationDependencyPr: onDisconnected()
2021-04-09 15:19:43.629 5902-5976/org.thoughtcrime.securesms W/WebsocketStrategy: Websocket timeout. (1140030 ms elapsed)
2021-04-09 15:19:54.415 5902-6394/org.thoughtcrime.securesms I/WebSocketConnection: connect()
2021-04-09 15:19:54.421 5902-6394/org.thoughtcrime.securesms I/ApplicationDependencyPr: onConnecting()
2021-04-09 15:19:55.056 5902-6396/org.thoughtcrime.securesms W/WebSocketConnection: onFailure()
    java.net.ProtocolException: Expected HTTP 101 response but was '403 Forbidden'
        at okhttp3.internal.ws.RealWebSocket.checkResponse(RealWebSocket.java:229)
        at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:196)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)
2021-04-09 15:19:55.057 5902-6396/org.thoughtcrime.securesms W/ApplicationDependencyPr: onAuthenticationFailure()
2021-04-09 15:19:55.057 5902-6396/org.thoughtcrime.securesms D/EventBus: No subscribers registered for event class org.thoughtcrime.securesms.events.ReminderUpdateEvent
2021-04-09 15:19:55.058 5902-6396/org.thoughtcrime.securesms D/EventBus: No subscribers registered for event class org.greenrobot.eventbus.NoSubscriberEvent
2021-04-09 15:19:55.058 5902-6396/org.thoughtcrime.securesms I/WebSocketConnection: onClose()
2021-04-09 15:19:55.058 5902-6396/org.thoughtcrime.securesms W/ApplicationDependencyPr: onDisconnected()

websocket的心跳包机制

D/WebSocketConnection: Sending keep alive...
W/AlarmSleepTimer: Setting alarm to wake up in 55000ms.
//WebSocketConnection.java

	...
  private static final int    KEEPALIVE_TIMEOUT_SECONDS = 55;

	...

  private class KeepAliveSender extends Thread {

    private AtomicBoolean stop = new AtomicBoolean(false);

    public void run() {
      while (!stop.get()) {
        try {
          sleepTimer.sleep(TimeUnit.SECONDS.toMillis(KEEPALIVE_TIMEOUT_SECONDS));

          Log.d(TAG, "Sending keep alive...");
          sendKeepAlive();
        } catch (Throwable e) {
          Log.w(TAG, e);
        }
      }
    }

    public void shutdown() {
      stop.set(true);
    }
  }

  private synchronized void sendKeepAlive() throws IOException {
    if (keepAliveSender != null && client != null) {
      byte[] message = WebSocketMessage.newBuilder()
                                       .setType(WebSocketMessage.Type.REQUEST)
                                       .setRequest(WebSocketRequestMessage.newBuilder()
                                                                          .setId(System.currentTimeMillis())
                                                                          .setPath("/v1/keepalive")
                                                                          .setVerb("GET")
                                                                          .build()).build()
                                       .toByteArray();

      if (!client.send(ByteString.of(message))) {
        throw new IOException("Write failed!");
      }
    }
  }
  
...

有个发送心跳包的线程,每隔55秒会发送一个心跳包,发送的请求的path是/v1/keepalive

websocket的接口地址

目前项目中使用的发送接收消息的 websocket 的接口地址和后台接口地址是一样的,只是后面的path路径不一样。
WebSocketConnection的代码逻辑中会将https替换为wss,将http替换为ws,然后建立WebSocket连接。

//WebSocketConnection.java

  public WebSocketConnection(String httpUri,
                             TrustStore trustStore,
                             Optional<CredentialsProvider> credentialsProvider,
                             String signalAgent,
                             ConnectivityListener listener,
                             SleepTimer timer,
                             List<Interceptor> interceptors,
                             Optional<Dns> dns)
  {
    this.trustStore          = trustStore;
    this.credentialsProvider = credentialsProvider;
    this.signalAgent         = signalAgent;
    this.listener            = listener;
    this.sleepTimer          = timer;
    this.interceptors        = interceptors;
    this.dns                 = dns;
    this.attempts            = 0;
    this.connected           = false;

    String uri = httpUri.replace("https://", "wss://").replace("http://", "ws://");

...

比如配置的地址是:http://192.168.1.1:80 ,那么WebSocketConnection创建的时候会将地址替换为ws://192.168.1.1:80 ,然后发起建立连接的请求。

nginx服务器需要支持wss

nginx服务器需要配置路由模块,这样才可以正常访问服务器上的ws/wss接口,否则只能访问http/https接口,访问ws/wss接口时在创建websocket时的握手阶段就会报错:404 not found 或者是 500 Server Error等。

404 not found

500 Server Error

或者是 500 Server Error

W/WebSocketConnection: onFailure()
    java.net.ProtocolException: Expected HTTP 101 response but was '500 Server Error'
        at okhttp3.internal.ws.RealWebSocket.checkResponse(RealWebSocket.java:229)
        at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:196)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)

服务器端代码报错:
在这里插入图片描述

403 Forbidden

如果服务器返回 403 Forbidden,说明客户端与websocket服务端是可以正常建立连接的,但是客户端认证失败:

securesms W/WebSocketConnection: onFailure()
    java.net.ProtocolException: Expected HTTP 101 response but was '403 Forbidden'
        at okhttp3.internal.ws.RealWebSocket.checkResponse(RealWebSocket.java:229)
        at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:196)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)

参看:WebSocket: Expected HTTP 101 response but was ‘403 Forbidden‘

403 Forbidden 是websocket连接成功后,在认证过程中如果认证失败会返回的状态码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值