Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websocket never receives any messages #2855

Closed
epitka opened this issue Aug 28, 2017 · 15 comments
Closed

Websocket never receives any messages #2855

epitka opened this issue Aug 28, 2017 · 15 comments

Comments

@epitka
Copy link

epitka commented Aug 28, 2017

Sync Gateway version

{"couchdb":"Welcome","vendor":{"name":"Couchbase Sync Gateway","version":1.4},"version":"Couchbase Sync Gateway/1.4.0(2;9e18d3e)"}

Operating system

The operating system you're running Sync Gateway on.
Windows 10

Config file

{
	"log":["*"],
    "databases": {
        "mobile_api": {
			"server": "http://172.18.0.2:8091",
			"username": "mobile_api",
			"password": "password",
            "users": {"GUEST": {"disabled": false, "admin_channels": ["*"]}},
            "sync": `function (doc, oldDoc) {
                if (doc.UserId) {
                    channel(doc.UserId);
                }
            }`
      }
  }
}

Log output

https://gist.github.com/epitka/fa9c3d07f4bc34e8eb0117c5203b4e2b

Expected behavior

What should have happened?
Should receive changes

Actual behavior

What actually happened?
Websocket closes immediately after being open

Steps to reproduce

  1. Started couchbase server and synch gateway
  2. insert some documents
  3. start console app that establishes web socket connection

Console app code that connects to web socket is following (.Net and WebSocketSharp library)

            using (var ws = new WebSocket("ws://localhost:4984/mobile_api/_changes?feed=websocket"))
            {
               try
                {
                    ws.OnMessage += (sender, e) =>
                        Console.WriteLine("Received Data: " + e.Data);

                    ws.OnError += (sender, e) =>
                        Console.WriteLine(e.Exception.ToString());

                    ws.OnOpen += (sender, e) =>
                    {
                        Console.WriteLine("sent options");
                        ws.Send("{since:0,include_docs:true}");
                    };

                    ws.Connect();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
                
                Console.ReadLine();

Interesting thing to note is that in OnOpen handler, if ws.IsAlive is false.

@tleyden
Copy link
Contributor

tleyden commented Aug 28, 2017

Can you try with http instead, with the same parameters, and see if there are any errors?

@epitka
Copy link
Author

epitka commented Aug 28, 2017

That does not work, as 'http' is not part of the scheme for websockets, code throws an exception that uri is invalid. Weird enough it establishes connection, as can be seen from logs, but immediately closes it.

@tleyden
Copy link
Contributor

tleyden commented Aug 28, 2017

No I just meant to try to query the _changes feed endpoint in a non-websocket manner, like with curl, and use the same parameters.

It might be easier to diagnose.

@tleyden
Copy link
Contributor

tleyden commented Aug 28, 2017

@epitka
Copy link
Author

epitka commented Aug 28, 2017

I've looked at that, as well as
this before I posted a question.

@tleyden
Copy link
Contributor

tleyden commented Aug 28, 2017

So everything worked fine w/ the non-websocket changes feed?

@epitka
Copy link
Author

epitka commented Aug 28, 2017

I can hit it with Postman, and I get results back, yes.

@tleyden
Copy link
Contributor

tleyden commented Aug 28, 2017

@snej does anything jump out at you about this websocket usage?

@epitka
Copy link
Author

epitka commented Aug 28, 2017

This works from same console app, I get changes

            var request = WebRequest.CreateHttp("http://localhost:4984/mobile_api/_changes");

            request.Method = WebRequestMethods.Http.Post;
            request.ContentType = "application/json; charset=utf-8";
            
            using (var streamWriter = new StreamWriter(request.GetRequestStream()))
            {
                var json = "{ \"since\":0, \"include_docs\":true}";

                streamWriter.Write(json);
                streamWriter.Flush();
            }

            var response = (HttpWebResponse)request.GetResponse();
            using (var streamReader = new StreamReader(response.GetResponseStream()))
            {
                var responseText = streamReader.ReadToEnd();
                Console.WriteLine(responseText);   
            }

but this part does not, it throws Bad Request error.

  var request = WebRequest.CreateHttp("http://localhost:4984/mobile_api/_changes?feed=websocket");

                request.Connection = "Upgrade";
                request.Headers.Add(HttpRequestHeader.Upgrade,"websocket");
                request.Method = WebRequestMethods.Http.Get;

                var response = await request.GetResponseAsync();

@snej
Copy link
Contributor

snej commented Aug 28, 2017

I don't see anything, but I've never used that client API.
Is there an OnClose handler you can register, to get confirmation that it's closed the connection?
If you take out the ws.Send call, does the connection still close?

@snej
Copy link
Contributor

snej commented Aug 28, 2017

but this part does not, it throws Bad Request error.

I'm not surprised. There are other parameters you'd have to add, to make that a valid WebSocket connect request.

Have you tried packet-sniffing with Charles or WireShark or something like that?

@epitka
Copy link
Author

epitka commented Aug 28, 2017

@snej: No I have not. I am just following documentation, and these were the options that were mentioned.

@epitka
Copy link
Author

epitka commented Aug 28, 2017

@snej:
Yes there is Close event handler as well.

                ws.OnClose += (sender, args) =>
                {
                    Console.WriteLine("Closed");
                };

So what I get in console as output is : Open, Sent Options, Closed.

@snej
Copy link
Contributor

snej commented Aug 28, 2017

Looking at our client code, we send the initial options message as binary not text. Try doing that.

@epitka
Copy link
Author

epitka commented Aug 28, 2017

@snej: Wooohooo, you're the man. It worked. I probably should write up a doc for .Net users

try
{
    ws.OnClose += (sender, args) =>
    {
        Console.WriteLine("Closed");
    };

    ws.OnMessage += (sender, e) =>
        Console.WriteLine("Received Data: " + e.Data);

    ws.OnError += (sender, e) =>
        Console.WriteLine(e.Exception.ToString());

    ws.OnOpen += (sender, e) =>
    {
        Console.WriteLine("state: " + ws.ReadyState.ToString());

                    
        var encoding = new ASCIIEncoding();
        var json = "{ \"since\":0, \"include_docs\":true}";
        byte[] data = encoding.GetBytes(json);

                    
        //ws.Send("{since:0,include_docs:true}");
        ws.Send(data);
        Console.WriteLine("sent options");
                    
    };
                
    ws.Connect();
                
}
catch (Exception e)
{
    Console.WriteLine(e);
    throw;
}

@epitka epitka closed this as completed Aug 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants