婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Swoole源碼中如何查詢Websocket的連接問題詳解

Swoole源碼中如何查詢Websocket的連接問題詳解

熱門標簽:ai電話機器人加盟代理 OMG地圖標注app 地圖標注視頻廣告入駐 gps 地圖標注軟件 400電話鄭州申請 招標自動語音外呼系統 中原區電話機器人價格 黔江400電話如何辦理 電銷機器人便宜的有嗎

問題

我們項目的 Websocket Server 使用的 Swoole,最近在搭建 beta 環境的時候發現 Websocket 協議雖然升級成功了,但是會出現定時重連,心跳、數據也一直沒有發送。項目的生產環境和 beta 一致,但是生產環境確沒有這個問題。

定位問題

為了方便調試 Swoole,以下測試是在本地環境下進行。

查看 PHP 日志

在 PHP 日志里,發現一條錯誤日志: ErrorException: Swoole\WebSocket\Server::push(): the connected client of connection[47] is not a websocket client or closed,說明 Websocket 連接已經 close 了。

抓包

既然連接被 close 掉了,那我們來看看是誰主動關閉的連接。Swoole 監聽的端口是 1215,通過 tcpdump -nni lo0 -X port 1215 可以看到,Swoole 在發出協議升級的響應報文后,又發出了 Fin 報文段,即 Swoole 主動斷開了連接,所以才會出現瀏覽器顯示 WebSocket 連接建立成功,但是又定時重連的問題。

10:22:58.060810 IP 127.0.0.1.1215 > 127.0.0.1.53823: Flags [P.], seq 1:185, ack 1372, win 6358, options [nop,nop,TS val 1981911666 ecr 1981911665], length 184
    0x0000:  4500 00ec 0000 4000 4006 0000 7f00 0001  E.....@.@.......
    0x0010:  7f00 0001 04bf d23f 9377 304a 6d2f 9604  .......?.w0Jm/..
    0x0020:  8018 18d6 fee0 0000 0101 080a 7621 9272  ............v!.r
    0x0030:  7621 9271 4854 5450 2f31 2e31 2031 3031  v!.qHTTP/1.1.101
    0x0040:  2053 7769 7463 6869 6e67 2050 726f 746f  .Switching.Proto
    0x0050:  636f 6c73 0d0a 5570 6772 6164 653a 2077  cols..Upgrade:.w
    0x0060:  6562 736f 636b 6574 0d0a 436f 6e6e 6563  ebsocket..Connec
    0x0070:  7469 6f6e 3a20 5570 6772 6164 650d 0a53  tion:.Upgrade..S
    0x0080:  6563 2d57 6562 536f 636b 6574 2d41 6363  ec-WebSocket-Acc
    0x0090:  6570 743a 2052 6370 3851 6663 446c 3146  ept:.Rcp8QfcDl1F
    0x00a0:  776e 666a 6377 3862 4933 6971 7176 4551  wnfjcw8bI3iqqvEQ
    0x00b0:  3d0d 0a53 6563 2d57 6562 536f 636b 6574  =..Sec-WebSocket
    0x00c0:  2d56 6572 7369 6f6e 3a20 3133 0d0a 5365  -Version:.13..Se
    0x00d0:  7276 6572 3a20 7377 6f6f 6c65 2d68 7474  rver:.swoole-htt
    0x00e0:  702d 7365 7276 6572 0d0a 0d0a            p-server....
10:22:58.060906 IP 127.0.0.1.53823 > 127.0.0.1.1215: Flags [.], ack 185, win 6376, options [nop,nop,TS val 1981911666 ecr 1981911666], length 0
    0x0000:  4500 0034 0000 4000 4006 0000 7f00 0001  E..4..@.@.......
    0x0010:  7f00 0001 d23f 04bf 6d2f 9604 9377 3102  .....?..m/...w1.
    0x0020:  8010 18e8 fe28 0000 0101 080a 7621 9272  .....(......v!.r
    0x0030:  7621 9272                                v!.r
10:22:58.061467 IP 127.0.0.1.1215 > 127.0.0.1.53823: Flags [F.], seq 185, ack 1372, win 6358, options [nop,nop,TS val 1981911667 ecr 1981911666], length 0
    0x0000:  4500 0034 0000 4000 4006 0000 7f00 0001  E..4..@.@.......
    0x0010:  7f00 0001 04bf d23f 9377 3102 6d2f 9604  .......?.w1.m/..
    0x0020:  8011 18d6 fe28 0000 0101 080a 7621 9273  .....(......v!.s
    0x0030:  7621 9272                                v!.r

追蹤 Swoole 源碼

我們現在知道了是 Swoole 主動斷開了連接,但它是在什么時候斷開的,又為什么要斷開呢?就讓我們從源碼一探究竟。

從抓包結果看,發出響應報文到 close 連接的時間很短,所以猜測是握手階段出了問題。從響應報文可以看出,Websocket 連接是建立成功的,推測 swoole_websocket_handshake() 的結果應該是 true,那么連接應該是在 swoole_websocket_handshake() 里 close 的。

// // swoole_websocket_server.cc
int swoole_websocket_onHandshake(swServer *serv, swListenPort *port, http_context *ctx)
{
  int fd = ctx->fd;
  bool success = swoole_websocket_handshake(ctx);
  if (success)
  {
    swoole_websocket_onOpen(serv, ctx);
  }
  else
  {
    serv->close(serv, fd, 1);
  }
  if (!ctx->end)
  {
    swoole_http_context_free(ctx);
  }
  return SW_OK;
}

追蹤進 swoole_websocket_handshake() 里,前面部分都是設置響應的 header,響應報文則是在 swoole_http_response_end() 里發出的,它的結果也就是 swoole_websocket_handshake 的結果。

// swoole_websocket_server.cc
bool swoole_websocket_handshake(http_context *ctx)
{
  ...

  swoole_http_response_set_header(ctx, ZEND_STRL("Upgrade"), ZEND_STRL("websocket"), false);
  swoole_http_response_set_header(ctx, ZEND_STRL("Connection"), ZEND_STRL("Upgrade"), false);
  swoole_http_response_set_header(ctx, ZEND_STRL("Sec-WebSocket-Accept"), sec_buf, sec_len, false);
  swoole_http_response_set_header(ctx, ZEND_STRL("Sec-WebSocket-Version"), ZEND_STRL(SW_WEBSOCKET_VERSION), false);

    ...

  ctx->response.status = 101;
  ctx->upgrade = 1;

  zval retval;
  swoole_http_response_end(ctx, nullptr, retval);
  return Z_TYPE(retval) == IS_TRUE;
}

從 swoole_http_response_end() 代碼中我們發現,如果 ctx->keepalive 為 0 的話則關閉連接,斷點調試下發現還真就是 0。至此,連接斷開的地方我們就找到了,下面我們就看下什么情況下 ctx->keepalive 設置為 1。

// swoole_http_response.cc
void swoole_http_response_end(http_context *ctx, zval *zdata, zval *return_value)
{
  if (ctx->chunk) {
    ...
  } else {
    ...

      if (!ctx->send(ctx, swoole_http_buffer->str, swoole_http_buffer->length))
    {
      ctx->send_header = 0;
      RETURN_FALSE;
    } 
  }

  if (ctx->upgrade  !ctx->co_socket) {
    swServer *serv = (swServer*) ctx->private_data;
    swConnection *conn = swWorker_get_connection(serv, ctx->fd);

    // 此時websocket_statue 已經是WEBSOCKET_STATUS_ACTIVE,不會走進這步邏輯
    if (conn  conn->websocket_status == WEBSOCKET_STATUS_HANDSHAKE) {
      if (ctx->response.status == 101) {
        conn->websocket_status = WEBSOCKET_STATUS_ACTIVE;
      } else {
        /* connection should be closed when handshake failed */
        conn->websocket_status = WEBSOCKET_STATUS_NONE;
        ctx->keepalive = 0;
      }
    }
  }

  if (!ctx->keepalive) {
    ctx->close(ctx);
  }
  ctx->end = 1;
  RETURN_TRUE;
}

最終我們找到 ctx->keepalive 是在 swoole_http_should_keep_alive() 里設置的。從代碼我們知道,當 HTTP 協議是 1.1 版本時,keepalive 取決于 header 沒有設置 Connection: close;當為 1.0 版本時,header 需設置 Connection: keep-alive。

Websocket 協議規定,請求 header 里的 Connection 需設置為 Upgrade,所以我們需要改用 HTTP/1.1 協議。

int swoole_http_should_keep_alive (swoole_http_parser *parser)
{
 if (parser->http_major > 0  parser->http_minor > 0) {
  /* HTTP/1.1 */
  if (parser->flags  F_CONNECTION_CLOSE) {
   return 0;
  } else {
   return 1;
  }
 } else {
  /* HTTP/1.0 or earlier */
  if (parser->flags  F_CONNECTION_KEEP_ALIVE) {
   return 1;
  } else {
   return 0;
  }
 }
}

解決問題

從上面的結論我們可以知道,問題的關鍵點在于請求頭的 Connection 和 HTTP 協議版本。

后來問了下運維,生產環境的 LB 會在轉發請求時,會將 HTTP 協議版本修改為 1.1,這也是為什么只有 beta 環境存在這個問題,nginx 的 access_log 也印證了這一點。

那么解決這個問題就很簡單了,就是手動升級下 HTTP 協議的版本,完整的 nginx 配置如下。

upstream service {
  server 127.0.0.1:1215;
}

server {
  listen 80;
  server_name dev-service.ts.com;

  location / {
    proxy_set_header Host $http_host;
    proxy_set_header Scheme $scheme;
    proxy_set_header SERVER_PORT $server_port;
    proxy_set_header REMOTE_ADDR $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_http_version 1.1;

    proxy_pass http://service;
  }
}

重啟 Nginx 后,Websocket 終于正常了~

總結

到此這篇關于Swoole源碼中如何查詢Websocket的連接問題的文章就介紹到這了,更多相關Swoole源碼查詢Websocket連接問題內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 詳解PHP Swoole與TCP三次握手
  • Swoole擴展的6種模式深入詳解
  • php中Swoole的熱更新實現代碼實例
  • swoole鎖的機制代碼實例講解
  • windows系統php環境安裝swoole具體步驟
  • linux系統虛擬主機開啟支持Swoole Loader擴展的方法
  • 在Windows系統上安裝Cygwin搭建Swoole測試環境的圖文教程
  • php使用goto實現自動重啟swoole、reactphp、workerman服務的代碼
  • Centos7安裝swoole擴展操作示例
  • 詳解Swoole TCP流數據邊界問題解決方案

標簽:孝感 哈密 濟源 那曲 阿里 日照 北京 池州

巨人網絡通訊聲明:本文標題《Swoole源碼中如何查詢Websocket的連接問題詳解》,本文關鍵詞  Swoole,源碼,中,如何,查詢,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Swoole源碼中如何查詢Websocket的連接問題詳解》相關的同類信息!
  • 本頁收集關于Swoole源碼中如何查詢Websocket的連接問題詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    亚洲成精国产精品女| 欧美日韩精品欧美日韩精品一 | 欧美性生活影院| caoporen国产精品视频| 国产精品一区二区在线看| 韩国精品一区二区| 国产在线乱码一区二区三区| 精品系列免费在线观看| 美日韩一区二区三区| 黑人精品欧美一区二区蜜桃 | 亚洲另类在线一区| 一区二区视频在线| 亚洲一区二区三区四区中文字幕| 一区二区三区四区不卡在线 | 国产裸体歌舞团一区二区| 国产资源精品在线观看| 丁香激情综合国产| 色婷婷综合视频在线观看| 欧美日韩三级一区二区| 91精品国产乱码久久蜜臀| 欧美大片在线观看一区二区| 精品国产乱码91久久久久久网站| 久久老女人爱爱| 国产精品久久久久三级| 亚洲国产中文字幕| 久久99精品国产麻豆婷婷洗澡| 国产成人精品亚洲日本在线桃色| 成人app软件下载大全免费| 欧美性大战久久久久久久蜜臀| 欧美日韩在线三区| 国产欧美日韩一区二区三区在线观看| 国产精品视频一二三区| 香蕉加勒比综合久久| 国产精品一区不卡| 欧美日韩亚洲国产综合| 久久综合九色综合97_久久久| 国产精品成人网| 日韩精品一卡二卡三卡四卡无卡| 狠狠色丁香久久婷婷综| 在线视频欧美精品| 久久综合久久99| 日韩高清一区在线| 成人黄色在线网站| 日韩欧美在线影院| 一区二区三区在线影院| 国产成人在线影院| 在线播放91灌醉迷j高跟美女| 中文字幕欧美三区| 久久99久久精品欧美| 欧美视频在线观看一区| 中文字幕欧美区| 日本vs亚洲vs韩国一区三区二区| 色一情一乱一乱一91av| 久久久久久电影| 天堂一区二区在线免费观看| 91丨九色丨黑人外教| 久久久久久毛片| 久久99热99| 日韩天堂在线观看| 日韩精品一二三| 精品视频一区二区不卡| 一区二区不卡在线视频 午夜欧美不卡在| 狠狠狠色丁香婷婷综合激情| 日韩美女在线视频| 美女久久久精品| 日韩欧美www| 麻豆精品久久久| 91精品蜜臀在线一区尤物| 午夜久久久久久久久久一区二区| 欧美性大战久久久久久久| 亚洲裸体在线观看| 在线观看精品一区| 亚洲 欧美综合在线网络| 欧洲一区在线电影| 亚洲国产视频直播| 欧洲一区二区三区在线| 亚洲精品国产一区二区三区四区在线 | 免费视频最近日韩| 在线观看不卡视频| 国产精品久久毛片a| 国产一区在线观看麻豆| 日韩一区二区三区精品视频 | 久久国产精品第一页| 欧美精品高清视频| 午夜精品在线视频一区| 欧美私人免费视频| 午夜私人影院久久久久| 欧美体内she精视频| 国产欧美一区二区精品婷婷| 成人免费毛片片v| 国产精品传媒入口麻豆| 99久久综合99久久综合网站| 国产亚洲一区二区在线观看| 极品少妇一区二区三区精品视频| 91精品国产综合久久精品麻豆| 亚洲成人免费视频| 日韩区在线观看| 国产一区中文字幕| 国产情人综合久久777777| 国产一区 二区 三区一级| 久久亚洲精品国产精品紫薇| 国产麻豆精品在线| 欧美va亚洲va| 91久久线看在观草草青青| 亚洲无线码一区二区三区| 欧美丝袜丝交足nylons图片| 日本成人在线看| 精品国产成人在线影院| 成人毛片老司机大片| 欧美激情一区二区三区| 欧美日韩成人高清| 精品一区二区三区免费观看 | 日韩视频一区在线观看| 国产又粗又猛又爽又黄91精品| 久久综合久久99| 91蜜桃在线观看| 青娱乐精品在线视频| 日本一区二区三区国色天香| 不卡一卡二卡三乱码免费网站| 国产精品毛片无遮挡高清| 91精品久久久久久蜜臀| 懂色av中文字幕一区二区三区 | 久久精品99国产精品日本| 中文字幕日韩欧美一区二区三区| 欧美色图一区二区三区| 另类欧美日韩国产在线| 亚洲欧美综合网| 欧美日韩国产首页| 丰满岳乱妇一区二区三区| 亚洲欧美日韩国产综合| 国产日产精品1区| 欧美日韩成人综合天天影院 | 欧美精品国产精品| 成人免费毛片app| 无码av免费一区二区三区试看| 26uuu国产在线精品一区二区| 91久久精品国产91性色tv| 国产在线精品一区二区三区不卡| 一区二区在线电影| 国产精品欧美一级免费| 日韩精品中文字幕在线不卡尤物| 91天堂素人约啪| 久久99九九99精品| 午夜激情久久久| 亚洲视频在线一区观看| 久久久久久久久久久久久夜| 日韩欧美色综合网站| 欧美亚洲综合久久| 99久久伊人精品| 国产成人av影院| 国产一区二区免费视频| 亚洲午夜久久久久久久久电影院| 国产精品美女www爽爽爽| 久久综合狠狠综合| 精品久久久久久久久久久久包黑料| 欧美日韩中字一区| 欧美在线一区二区| 色呦呦国产精品| 欧美电影影音先锋| 欧美日韩美女一区二区| 欧美亚洲国产怡红院影院| 色噜噜狠狠成人中文综合| 波多野结衣亚洲一区| 成人激情校园春色| 在线观看视频一区二区欧美日韩| 99re6这里只有精品视频在线观看| 国产一区福利在线| 国产成人午夜精品影院观看视频 | 精品国产乱码久久久久久牛牛| 色综合久久天天| 欧美乱熟臀69xxxxxx| 欧美精选午夜久久久乱码6080| 欧美午夜寂寞影院| 91.com视频| 精品日韩在线一区| 日韩视频免费观看高清完整版在线观看 | 日韩美女精品在线| 一区二区三区影院| 亚洲制服丝袜av| 天天综合日日夜夜精品| 天堂一区二区在线免费观看| 五月天一区二区三区| 久久成人综合网| jiyouzz国产精品久久| 色狠狠一区二区三区香蕉| 欧美视频你懂的| 日韩欧美精品在线视频| 亚洲欧美日韩一区| 日本午夜精品视频在线观看| 狠狠狠色丁香婷婷综合激情| 成人福利视频网站| 欧美欧美欧美欧美首页| 欧美在线一区二区三区| 欧美国产成人在线| 亚洲高清免费视频| 国产精一区二区三区| 色呦呦国产精品| 精品免费日韩av| 国产片一区二区| 激情国产一区二区|