Getting disconnected as soon as I connect to PubSub C#

Hi.
I’m using C# to check the Twitch PubSub API. I’ve settled on the WebSocketSharp package to actually connect etc.
However, I’m being disconnected as soon as I connect. I did some debugging, and the code it’s giving me is 1001, which apparently means “Going away”. What I can’t figure out, is why it keeps going away? I have a feeling it’s just giving up after it connects, I just can’t identify where it’s wrong. :slight_smile:

Here’s the code:
WebSocket socket = new WebSocket("wss://pubsub-edge.twitch.tv");

using (socket)
            {
                socket.OnOpen += (sender, e) =>
                {
                    timer = new Timer();
                    timer.Interval = 240000;
                    timer.Elapsed += threadLoop;
                    timer.Start();
                    Console.WriteLine("Connected to " + socket.Url);
                    socket.Send(messageSubscribe);
                    Console.Write("Sent message to subscribe - " + messageSubscribe);
                };

                socket.OnError += (sender, e) =>
                {
                    Console.Write("Encountered error - " + e.Message);
                };
                socket.OnMessage += (sender, e) =>
                {
                    Console.WriteLine("Message received - " + e.Data);
                };
                socket.OnClose += (sender, e) =>
                {
                    Console.WriteLine("Disconnected from websocket - " + socket.Url + e.Reason + e.Code);
                    timer.Stop();
                };

                socket.

On the socket.Send() line, it gives me errors, saying “This operation is not available in: closing”

Any replies would be greatly appreciated!

  • Mike

You have to send a LISTEN command within 15s of connecting. Otherwise, you’ll be disconnected. Are you sending the command fast enough?

1 Like

It’s being sent instantly, as soon as it connects to the servers, it’s sending the listen command, but it’s still not fast enough (gets an error saying the operation is not available in: closing )

And you’re sending a valid OAuth token for the channel where you’re listening? It sounds like it could be something wrong with the authentication or the timing.

I don’t think the connection is getting to that stage. Do I need authentication to actually connect? It doesn’t seem to stay connected long enough to send the JSON which contains the OAuth in the “LISTEN” command.

Thanks for the assistance :slight_smile:

I think this is a problem with WebSocketSharp. If you read their docs, it says this:

The WebSocket class inherits the System.IDisposable interface, so you can use the using statement. And the WebSocket connection will be closed with close status 1001 (going away) when the control leaves the using block.

Control must be leaving your using block and causing that 1001 status.

I’ve found there are frequently issues with WebSocketSharp when we try to connect to Discord or the Curse app - I switched the package out for ‘WebSocket4Net’ and it’s fixed a LOT of issues. Both are derived projects from the same top level project [SuperSocket], so should be an almost 1:1 swap for methods after the initial connection process.

That being said, the connection itself shouldn’t be wrapped in a using. There needs to be a shutdown method that uses a try:catch:finally syntax, and the finally calls the shutdown/dispose method. (Basically, hold a reference to the socket until you actually intend for the application to shut down the socket)

Well, technically you can use a using, but if you do you have to wrap your whole class in it, which is usually pretty gross.

Hmm, thank you for the reply. I’ll give that other package a try, and see if it works better!

Oh I missed that bit! So even if I’m calling from the using block, to a method outside, that method outside the block will end it?

If you do something like this, you will get a reference to a disposed object.

Pseudo code, in the interest of brevity.

public static void SomeMethod()
{
var iAmActuallyDisposed = OpenSocket();
}

public static Socket OpenSocket()
{
using(var socket = new Socket()){
socket.Open();
return socket;
}
}

because when the method returns, the ‘using’ loses scope.

I gave this code a go, and it seemed to work fairly well. However, it doesn’t seem to work with the event listeners (so I can’t tell if it fixed my original problem). It didn’t appear to connect, so I had to move the “socket.connect()” from the OpenSocket method, and into the “SomeMethod” instead, using “iAmActuallyDisposed.connect()”
Now, it does connect, but none of the event listeners are triggering, such as onOpen etc.
Any ideas?

That code is an example of bad code that will result in an object disposed. You don’t want to use that.

Read the documentation on WebSocket4Net (or WebSocketSharp if you’re still using that.)

WebSocket4Net docs: https://websocket4net.codeplex.com/documentation

Oh, I misread that completely then, sorry :laughing: Wow, shows I should have caffeine before working, huh :stuck_out_tongue_winking_eye:
I’ll remove WebSocketSharp and try WebSocket4Net, and keep you updated. Thanks!

Okay, I gave WebSocket4Net a go, and it seems to work pretty well. From what I can see, it’s staying connected, which is a good start! It also appears to send the JSON message for bits.
I read on the API that when I send the JSON message, I’ll receive a message in return. However, this doesn’t appear to be the case. I don’t receive any messages, or data (but I’m also not receiving any errors). It logs that the connection was opened, and also logs when the connection closes, so I know it’s definitely staying connected this time, so using WebSocket4Net seems like a good start.

The JSON message I’m trying to send has a LISTEN command, to listen for any cheers that come through. I’m not partnered on Twitch, so I don’t have the OAuth key or anything else to test it, so I left it empty. I at least expected an error, or message back though (which the Documentation specifies will happen). So either the message isn’t getting through, or maybe I did the formatting wrong.

var messageSubscribe = @"
   {
   ""type"": ""LISTEN"",
   ""nonce"": ""somerandomstring"",
  ""data"": {
        ""topics"": [""channel-bitsevents.38197393""],
        ""auth_token"": """",
       }
 }
";

I know that the way I’ve written it is probably terrible, but it was the fastest way, and ya know, fast is great for programming… I would put a Kappa emote but the developer forums don’t have it!?
Anyway, as stated I’d expect at least an error if the formatting was wrong or something.

Thanks again for the help!

When you create your socket, your application needs to wire up the ‘messagereceived’ event (see that page i linked). Basically the method is called any time messages arrive over the wire. When the event fires, you’ll want to apply your application logic to parse the message and handle it.

An example might look a bit like this:

 ws = new WebSocket(CurrentGatewayUrl);
ws.MessageReceived += (sender, e) =>
            {
                try
                {
                    var data = JsonConvert.DeserializeObject<TwitchMessageEnvelope>(e.Message);
                    if(data != null)
                    {
                        CallHandlingMethod(data);
                    }
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }

Every time you receive a message, the .MessageReceived event will fire, and the message data will exist in the variable ‘e’. The code tries to deserialize the json object using the model ‘TwitchMessageEnvelope’ (which you have to make, based on API docs) and if it successfully deserializes (object != null), call the handling method to process the envelope object. (The handling object would deal with things like parsing the message for bits, or getting video information, or w/e endpoint your accessing)

OAuth keys are also not specific to partners, if you don’t have bits enabled you’ll probably get an error, but I haven’t actually tested that scenario - but you can still request the proper permissions in your app flow.

*Note: JsonConvert comes from the NuGet package ‘NewtonSoft Json’ If you don’t have it, you want it. Go get it.

Hm, I have the event declared (sorry should’ve provided this in the message previously), and have tried both creating the event inside of the method, and then outside as seen in the code below.
Do I need to actually parse the message in order to see it? Or is mine enough to see it?

 socket.Opened += (sender, e) =>
            {
                
                Console.WriteLine("Connected to Twitch PubSub - " + socket.State);
                socket.Send(messageSubscribe);
                Console.Write("Sent message to subscribe - " + messageSubscribe);
            };
            
            socket.Error += (sender, e) =>
            {
                Console.Write("Encountered error - " + e);
            };
            socket.MessageReceived += messageReceived;
            socket.Closed += closed;
            socket.DataReceived += dataReceived;
            socket.Open();



        }
        public void dataReceived(object sender, DataReceivedEventArgs e)
        {
           Console.WriteLine("Data received - " + e.Data);
        }
        public void messageReceived(object sender, MessageReceivedEventArgs e)
        {
           Console.WriteLine("Message received - " + e.Message);
        }

It should be enough, but i suspect you’re going to have problems with the send on socket open, try a sleep for 2s and see if it works (and if you’re actually calling send, and messageSubscribe is the listen request)

Thanks. I gave that a go, created a timer with an interval of 5000 ticks, and sent the message inside there (obviously stopped the timer to prevent loops), but still no luck. It logs that the message has been sent successfully, but nothing comes back from the servers. I don’t suppose it needs a port for the server? I left it without a port assuming it would know the correct port anyway.

@DallasNChains @tournymasterbotCurse I know at this point we’ve almost given up on trying to figure out what’s wrong, but I did find something relatively useful.

https://www.websocket.org/echo.html - This site allows me to connect to servers and test it. I connected to the Twitch server, and tried sending the message I was trying to send, and it didn’t work. I received nothing in return. However… I did receive a PONG, when I sent the PING json message. So the server is definitely responding, and as far as I can tell, the connection is remaining active. So all I can think of is that somehow, my message is formatted incorrectly. I tried sending the example message on the documentation page, expecting an error at least, and got nothing in reply. So I’m not sure if it actually works with the LISTEN command, but it’s a step closer, right? I hope this helps, sort of :slight_smile:

Thanks,
Mike

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.