dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.23k stars 1.57k forks source link

Websocket is closed imidiately after initiating the connection #34838

Open jeroenvervaeke opened 6 years ago

jeroenvervaeke commented 6 years ago

Environment

Intro

I've been working on a very simple application using both flutter and actix-web (rust). As a test I set up a echo websocket server in rust and added a simple websocket in flutter.

Both applications work fine by themselves but not when combined:

Issue

The issue is the following

  1. Start websocket server
  2. Start flutter or dart script
  3. Flutter sends an upgrade request to the websocket server
  4. Websocket server responds with a HTTP/1.1 101 Switching Protocols
  5. Flutter immediately sends a close message and closes the socket before sending any data

I tried to figure out if it was a flutter issue or a dart issue so I boiled the dart code down to the dart code below and I'm still able to reproduce the issue. I also included the wireshark results from both the good and bad request.

Code

import 'dart:io';
import 'dart:async';

main(List<String> arguments) async {
  var ws = await WebSocket.connect("ws://127.0.0.1:8080/ws/", compression: CompressionOptions(enabled: false));
  ws.listen((data) => print(data));
  ws.add("Hello server!");

  await Future.delayed(Duration(seconds: 15));
  ws.close();
}

Websocket server code:

extern crate actix;
extern crate actix_web;

use actix::*;
use actix_web::*;

struct Ws;
impl Actor for Ws {
    type Context = ws::WebsocketContext<Self>;
}

impl StreamHandler<ws::Message, ws::ProtocolError> for Ws {
    fn handle(&mut self, msg: ws::Message, ctx: &mut Self::Context) {
        match msg {
            ws::Message::Ping(msg) => ctx.pong(&msg),
            ws::Message::Text(text) => ctx.text(text),
            _ => println!("Received something else"),
        }
    }

    fn started(&mut self, ctx: &mut Self::Context) {
        println!("Client joined");
    }

    fn finished(&mut self, _ctx: &mut Self::Context) {
        println!("Client left");
    }
}

fn main() {
    server::new(|| App::new().resource("/ws/", |r| r.f(|req| ws::start(req, Ws)))).bind("127.0.0.1:8080").unwrap().run();
}

Http requests

Good request (echo.websocket.org)

GET / HTTP/1.1
user-agent: Dart/2.1 (dart:io)
connection: Upgrade
cache-control: no-cache
accept-encoding: gzip
content-length: 0
sec-websocket-version: 13
host: echo.websocket.org
sec-websocket-key: sc5c5AtILUv4qvRksqdQqg==
upgrade: websocket

HTTP/1.1 101 Web Socket Protocol Handshake
Connection: Upgrade
Date: Tue, 16 Oct 2018 18:28:36 GMT
Sec-WebSocket-Accept: 5rA1FF1jukiuSQraadfIE2zYLN4=
Server: Kaazing Gateway
Upgrade: websocket

...q....B..Q]...K....X.iy.
Hello server!..

Bad request (echo.websocket.org)

GET /ws/ HTTP/1.1
user-agent: Dart/2.1 (dart:io)
connection: Upgrade
cache-control: no-cache
accept-encoding: gzip
content-length: 0
sec-websocket-version: 13
host: 192.168.1.8:8080
sec-websocket-key: 4oNDFgKkxN8RoLt2b6bIjw==
upgrade: websocket

HTTP/1.1 101 Switching Protocols
upgrade: websocket
sec-websocket-accept: JpD8+yK5o8AzNtCEGJOZWo2USxc=
connection: upgrade
date: Tue, 16 Oct 2018 18:34:13 GMT

...:..
unixzii commented 5 years ago

I also have that problem, the flutter_tools cannot establish any WebSocket connections with the VM side, and it behaved just like what this issue described.

unixzii commented 4 years ago

My similar problem has been solved, just after removing all http proxy settings, all things performed well.