Twitter stream with web socket MatchingTweetReceived not triggered in twitterinvl - c#

I am creating a twiiter stremaing MVC controller. The controller method is implemented as a web socket.
Ref: Connecting with websockets to windows azure using MVC controllerenter link description here
I want to display the twitter stream in the UI. I am using twitterinvl. My code is included below. The stream event MatchingTweetReceived are not getting triggered from the controller method.
Any help on this is highly appreciated.
Controller action method.
public ActionResult About()
{
if (ControllerContext.HttpContext.IsWebSocketRequest)
{
ControllerContext.HttpContext.AcceptWebSocketRequest(DoTalking);
}
return new HttpStatusCodeResult(HttpStatusCode.SwitchingProtocols);
}
Rest of the code
public async Task DoTalking(AspNetWebSocketContext context)
{
try
{
WebSocket socket = context.WebSocket;
while (true)
{
var buffer = new ArraySegment<byte>(new byte[1024]);
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
if (socket.State == WebSocketState.Open)
{
string userMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
string outmessage = "Empty";
//userMessage = "You sent: " + userMessage + " at " + DateTime.Now.ToLongTimeString();
Auth.SetUserCredentials("<<credential>>", "<<credential>>", "<<credential>>", "<<credential>>");
var stream = Stream.CreateFilteredStream();
stream.AddTrack("enterhash");
stream.MatchingTweetReceived += (sender, theTweet) =>
{
outmessage = theTweet.Tweet.CreatedBy.ToString() + theTweet.Tweet.CreatedAt + theTweet.Tweet;
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMessage));
//Console.WriteLine($"Tweet: {theTweet.Tweet.CreatedAt} {theTweet.Tweet}");
socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
};
stream.StartStreamMatchingAllConditions();
Trace.WriteLine(outmessage);
//await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
else
{
break;
}
}
}
catch (Exception ex)
{
}
}

Related

GetUpdate keeps sending updates endlessly

i'm writing a Telegram bot without using any library but only using HTTP request. The problem is that i keep getting updates endlessly when i start long polling, here's my code:
public async Task StartPolling(string[] allowedUpdates = default!)
{
int messageOffset = 0;
while (true)
{
Console.WriteLine("Sending GetUpdate with offset " + messageOffset);
var updates = await GetUpdatesAsync(offset: messageOffset, timeout: Convert.ToInt32(s_httpClient.Timeout.TotalSeconds), allowedUpdates: allowedUpdates);
Console.WriteLine("Receving " + updates.Length + " updates...");
foreach (var update in updates!)
{
HandleUpdatesAsync(update);
messageOffset = update.UpdateId + 1;
Console.WriteLine("MessageId = " + update.UpdateId);
}
Console.WriteLine("Offsett = " + messageOffset);
}
}
public async Task<Update[]?> GetUpdatesAsync(int offset = 0, int limit = 100, int timeout = 0, string[]? allowedUpdates = default)
{
var request = new GetUpdatesRequest
{
Offset = offset,
Limit = limit,
Timeout = timeout,
AllowedUpdates = allowedUpdates ?? Array.Empty<string>(),
};
return await SendRequestAsync<Update[]>(request);
}
private async Task<T?> SendRequestAsync<T>(IRequest request)
{
var httpRequestMessage = new HttpRequestMessage(method: request.Method, requestUri: $"{_baseUrl}/{request.MethodName}")
{
Content = request.Content
};
try
{
var httpResponseMessage = await s_httpClient.SendAsync(httpRequestMessage);
var updatesJson = await httpResponseMessage.Content.ReadAsStreamAsync();
var response = await JsonSerializer.DeserializeAsync<Response<T>>(updatesJson, options);
return response!.Result;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
when i run the code and send a message to my bot it keeps printing the "Sending GetUpdate with offsett etc... here's the screenshot of the console
The only way to stop getting infinite updates is by closing the application or by manualy sending a getUpdate with the SAME offset of the code in the browser like this:
https://api.telegram.org/botXXXXXXXXXXXXXXX/getUpdates?offset=419787029
Sorry for my English :)

Websocket.ReceiveAsync causing a crash when a client disconnects without cancelling connection

DotNet Core 3.1 (running either Kestral or IIS)
I have the following loop, running in a Task for each connected client
using (var ms = new MemoryStream())
{
do
webSocketReceiveResult = await socket.ReceiveAsync(buffer, CancellationToken.None);
ms.Write(buffer.Array, buffer.Offset, webSocketReceiveResult.Count);
}
while (!webSocketReceiveResult.EndOfMessage);
When a client abruptly exits, network failure, crash or whatever and doesnt have a chance to close its connection, it crashes the whole class, and all tasks running. The webserver is still up and will accept all new connections, but all existing connections are terminated.
The error is : 'The remote party closed the WebSocket connection without completing the close handshake.'
which is expected, but I cannot try-catch it to preserve the rest of the connections?
Complete method here:
private static async Task SocketProcessingLoopAsync(ConnectedClient client)
{
_ = Task.Run(() => client.BroadcastLoopAsync().ConfigureAwait(false));
var socket = client.Socket;
var loopToken = SocketLoopTokenSource.Token;
var broadcastTokenSource = client.BroadcastLoopTokenSource; // store a copy for use in finally block
string sessionName = "";
string command = "";
int commandCounter = 0;
WebSocketReceiveResult webSocketReceiveResult = null;
try
{
var buffer = WebSocket.CreateServerBuffer(4096);
while (socket.State != WebSocketState.Closed && socket.State != WebSocketState.Aborted && !loopToken.IsCancellationRequested)
{
// collect all the bytes incoming
using (var ms = new MemoryStream())
{
do
{
webSocketReceiveResult = await socket.ReceiveAsync(buffer, CancellationToken.None);
ms.Write(buffer.Array, buffer.Offset, webSocketReceiveResult.Count);
}
while (!webSocketReceiveResult.EndOfMessage);
//var receiveResult = await client.Socket.ReceiveAsync(buffer, loopToken);
// if the token is cancelled while ReceiveAsync is blocking, the socket state changes to aborted and it can't be used
if (!loopToken.IsCancellationRequested)
{
// the client is notifying us that the connection will close; send acknowledgement
if (client.Socket.State == WebSocketState.CloseReceived && webSocketReceiveResult.MessageType == WebSocketMessageType.Close)
{
Console.WriteLine($"Socket {client.SocketId}: Acknowledging Close frame received from client");
broadcastTokenSource.Cancel();
await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Acknowledge Close frame", CancellationToken.None);
// the socket state changes to closed at this point
}
if (client.Socket.State == WebSocketState.Open)
{
if (webSocketReceiveResult.MessageType == WebSocketMessageType.Text)
{
// here we receive text instructioons from the clients
using (StreamReader reader = new StreamReader(ms, Encoding.UTF8))
{
ms.Seek(0, SeekOrigin.Begin);
command = reader.ReadToEnd().ToLower();
}
// var command = Encoding.UTF8.GetString(buffer.Array, 0, webSocketReceiveResult.Count).ToLower();
if (command.Contains("session:"))
{
// assign the client to a session, and inform them of their position in it
sessionName = command.Replace("session:", "");
if (!ClientControl.Sessions.ContainsKey(sessionName))
{
ClientControl.Sessions.TryAdd(sessionName, new BlockingCollection<ConnectedClient>());
}
ClientControl.Sessions[sessionName].Add(client);
// broadcast the collection count
Broadcast(ClientControl.Sessions[sessionName].Count.ToString(), client, true, sessionName);
Broadcast("Number of clients " + ClientControl.Sessions[sessionName].Count.ToString(), client, false, sessionName);
Broadcast("Number of clients " + ClientControl.Sessions[sessionName].Count.ToString(), client, true, sessionName);
}
else if (command.Contains("status:"))
{
string output = "<br/><h1>Sessions:</h1><br/><br/>";
foreach (var session in ClientControl.Sessions)
{
output += session.Key + " Connected Clients: " + session.Value.Count.ToString() + "<br/>";
}
Broadcast(output, client, true, "");
}
else if (command.Contains("ping"))
{
Console.WriteLine(command + " " + DateTime.Now.ToString() + " " + commandCounter);
}
}
else
{
// we just mirror what is sent out to the connected clients, depending on the session
Broadcast(ms.ToArray(), client, sessionName);
commandCounter++;
}
}
}
}// end memory stream
}
}
catch (OperationCanceledException)
{
// normal upon task/token cancellation, disregard
}
catch (Exception ex)
{
Console.WriteLine($"Socket {client.SocketId}:");
Program.ReportException(ex);
}
finally
{
broadcastTokenSource.Cancel();
Console.WriteLine($"Socket {client.SocketId}: Ended processing loop in state {socket.State}");
// don't leave the socket in any potentially connected state
if (client.Socket.State != WebSocketState.Closed)
client.Socket.Abort();
// by this point the socket is closed or aborted, the ConnectedClient object is useless
if (ClientControl.Sessions[sessionName].TryTake(out client))
socket.Dispose();
// signal to the middleware pipeline that this task has completed
client.TaskCompletion.SetResult(true);
}
}
Ok, couldn't get this to work, I have re-written the loop to look like this, it exits cleanly when a client hangs
do
{
cancellationTokenSource = new CancellationTokenSource(10000);
task = socket.ReceiveAsync(buffer, loopToken);
while (!task.IsCompleted && !SocketLoopTokenSource.IsCancellationRequested)
{
await Task.Delay(2).ConfigureAwait(false);
}
if (socket.State != WebSocketState.Open || task.Status != TaskStatus.RanToCompletion)
{
if (socket.State == WebSocketState.CloseReceived)
{
Console.WriteLine($"Socket {client.SocketId}: Acknowledging Close frame received from client");
broadcastTokenSource.Cancel();
await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Acknowledge Close frame", CancellationToken.None);
ClientControl.Sessions[sessionName].TryTake(out client);
}
Console.WriteLine("Client Left " + client.SocketId);
break;
}
ms.Write(buffer.Array, buffer.Offset, task.Result.Count);
}
while (!task.Result.EndOfMessage);

C# WebSocket.SendAsync() randomly gets stuck

I have used the following code to send using the System.Net.WebSocket from WPF after socket has connected
try
{
Console.WriteLine("Sending...");
await _ws.SendAsync(new ArraySegment<byte>(packet.GetBytes()), WebSocketMessageType.Binary, true, CancellationToken.None);
Console.WriteLine("Sent...");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
Calling code
if (!ValidateSettings()) return;
var hostname = TbHostname.Text.Trim();
var tcpport = TbTcpPort.Text.Trim();
_ws = new AchiWebSocket();
_streamTimer = new System.Threading.Timer(async s =>
{
var socket = (AchiWebSocket)s;
if (!_semaWs.Wait(0)) return;
UpdateBuffer();
var buffer = GetFrameBuffer();
var packet = new BinaryPacket(buffer.GetBytes());
if(socket.WebSocketState == null || socket.WebSocketState == WebSocketState.Closed)
await socket.Connect(new Uri("ws://" + hostname + "/superrfb"));
try
{
await socket.SendAsync(packet);
}
catch(Exception e)
{
Console.WriteLine("--" + e.Message);
}
finally
{
_semaWs.Release();
}
}, _ws, 0, 70);
Receiving Code (Asp.Net Core)
public async Task StartReceiveAsync(Action<Packet> onReceive)
{
WebSocketReceiveResult result;
var buffer = new byte[4 * 1024];
var stream = new MemoryStream();
do
{
result = await _ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
await stream.WriteAsync(buffer, 0, result.Count);
if (result.EndOfMessage)
{
var packet = BinaryPacket.FromRaw(stream.ToArray());
onReceive.Invoke(packet);
}
}
while (!result.CloseStatus.HasValue);
Dispose();
}
I do receive some data but the socket gets stuck in SendAsync after a few packets. It doesn't return even after waiting several minutes.
Ok I figured it out. My onReceive.Invoke() function was throwing exception sometimes causing the server to stop receiving. This made the receive buffer fill up and WebSocket.SendAsync to stuck and wait until the buffer is free. After wrapping the onReceive.Invoke() in try catch, the code is working fine now.
try
{
onReceive.Invoke(packet);
}
catch(Exception e)
{
Debug.WriteLine(e.Message);
}

UWP app cannot receive, only send, using sockets

I'm currently developing an UWP app which should have capability to be as a TCP server (using ports) so client can connect to it via other device and send requests and server responds with data.
I followed the Socket example on :Microsoft site, and got sample code working (in which server and client are both in same app)
I changed IP addresses and ports so i could use apps on 2 different machines with direct connection, I also made separate simple client application, using sample code from Here
Now problem is as follows: UWP app can successfully communicate with its own client method provided by Microsoft's sample, but is unable to communicate with console client program I made and was running on other. UWP can indeed connect with client and also send data, but it cannot receive data, the function streamReader.ReadLineAsync(); will wait infinitely long and that's all.
How do i make UWP app get the message client is sending and what i might be doing wrong ?
public sealed partial class MainPage : Page
{
static string PORT_NO = "1300";
const string SERVER_IP = "192.168.0.10";
public MainPage()
{
this.InitializeComponent();
outputText.Text = "Helloo";
StartConnection(SERVER_IP, PORT_NO);
//StartClient();
}
public async void StartConnection(string net_aadress, string port_nr)
{
try
{
var streamSocketListener = new StreamSocketListener();
// The ConnectionReceived event is raised when connections are received.
streamSocketListener.ConnectionReceived += this.StreamSocketListener_ConnectionReceived;
// Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use.
await streamSocketListener.BindServiceNameAsync(port_nr);
outputText.Text = "server is listening...";
}
catch (Exception ex)
{
Windows.Networking.Sockets.SocketErrorStatus webErrorStatus = Windows.Networking.Sockets.SocketError.GetStatus(ex.GetBaseException().HResult);
outputText.Text = (webErrorStatus.ToString() != "Unknown" ? webErrorStatus.ToString() : ex.Message);
}
}
private async void StreamSocketListener_ConnectionReceived(Windows.Networking.Sockets.StreamSocketListener sender, Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs args)
{
string request = "password";
string second;
/*
using (var streamReader = new StreamReader(args.Socket.InputStream.AsStreamForRead()))
{
request = await streamReader.ReadLineAsync();
}
*/
//await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => this.serverListBox.Items.Add(string.Format("server received the request: \"{0}\"", request)));
// Echo the request back as the response.
using (Stream outputStream = args.Socket.OutputStream.AsStreamForWrite())
{
using (var streamWriter = new StreamWriter(outputStream))
{
await streamWriter.WriteLineAsync(request);
await streamWriter.FlushAsync();
}
}
using (var streamReader = new StreamReader(args.Socket.InputStream.AsStreamForRead()))
{
second = await streamReader.ReadLineAsync();
}
using (Stream outputStream = args.Socket.OutputStream.AsStreamForWrite())
{
using (var streamWriter = new StreamWriter(outputStream))
{
await streamWriter.WriteLineAsync(second);
await streamWriter.FlushAsync();
}
}
//await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => this.serverListBox.Items.Add(string.Format("server sent back the response: \"{0}\"", request)));
sender.Dispose();
//await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => this.serverListBox.Items.Add("server closed its socket"));
}
private async void StartClient()
{
try
{
// Create the StreamSocket and establish a connection to the echo server.
using (var streamSocket = new Windows.Networking.Sockets.StreamSocket())
{
// The server hostname that we will be establishing a connection to. In this example, the server and client are in the same process.
var hostName = new Windows.Networking.HostName("localhost");
//this.clientListBox.Items.Add("client is trying to connect...");
await streamSocket.ConnectAsync(hostName, PORT_NO);
//this.clientListBox.Items.Add("client connected");
// Send a request to the echo server.
string request = "Hello, World!";
using (Stream outputStream = streamSocket.OutputStream.AsStreamForWrite())
{
using (var streamWriter = new StreamWriter(outputStream))
{
await streamWriter.WriteLineAsync(request);
await streamWriter.FlushAsync();
}
}
//this.clientListBox.Items.Add(string.Format("client sent the request: \"{0}\"", request));
// Read data from the echo server.
string response;
using (Stream inputStream = streamSocket.InputStream.AsStreamForRead())
{
using (StreamReader streamReader = new StreamReader(inputStream))
{
response = await streamReader.ReadLineAsync();
}
}
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
() =>
{
outputText.Text = "Client got back " + response;
}
);
}
//this.clientListBox.Items.Add("client closed its socket");
}
catch (Exception ex)
{
Windows.Networking.Sockets.SocketErrorStatus webErrorStatus = Windows.Networking.Sockets.SocketError.GetStatus(ex.GetBaseException().HResult);
//this.clientListBox.Items.Add(webErrorStatus.ToString() != "Unknown" ? webErrorStatus.ToString() : ex.Message);
}
}
}
Here is source code for Client application:
{
class Program
{
const int PORT_NUMBER = 1300;
const string SERVER_IP = "192.168.0.10";
static void Main(string[] args)
{
string textToSend = DateTime.Now.ToString();
string password = "Madis on loll";
string receiveddata;
try
{
Console.WriteLine("Client progrm started");
TcpClient client = new TcpClient(SERVER_IP, PORT_NUMBER);
NetworkStream nwStream = client.GetStream();
//System.Threading.Thread.Sleep(500);
//see, how long is packet
byte[] bytesToRead = new byte[client.ReceiveBufferSize];
int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
Console.WriteLine("Received : " + Encoding.ASCII.GetString(bytesToRead, 0, bytesRead));
byte[] password2 = ASCIIEncoding.ASCII.GetBytes(password);
Console.WriteLine("Sending : " + password);
nwStream.Write(password2, 0, password2.Length); //sending packet
byte[] receiveddata2 = new byte[client.ReceiveBufferSize];
int receiveddatalength = nwStream.Read(receiveddata2, 0, client.ReceiveBufferSize);
Console.WriteLine("Received : " + Encoding.ASCII.GetString(receiveddata2, 0, bytesRead));
}
catch (Exception ex)
{
Console.WriteLine("Connection error");
}
}
}
}
Found answer myself: main problem is with ReadLineAsync() in Server program: it waits and collects all the stream until it gets end of line character. In this case end of line was never sent and therefore server kept waiting infinitely.
Simplest fix was on Client side by simply adding end of line at the end of packet, like this:
before:
byte[] password2 = ASCIIEncoding.ASCII.GetBytes(password);
Console.WriteLine("Sending : " + password);
nwStream.Write(password2, 0, password2.Length); //sending packet
after:
byte[] newLine = Encoding.ASCII.GetBytes(Environment.NewLine);
byte[] password2 = ASCIIEncoding.ASCII.GetBytes(password);
Console.WriteLine("Sending : " + password);
nwStream.Write(password2, 0, password2.Length); //sending packet
nwStream.Write(newLine,0,newLine.Length);
Also 1 thing worth mentioning: current StreamSocketListener_ConnectionReceived is able to send only once, then it sets outputStream.CanWrite to false.
This can be solved by removing using() from writing and reading functions, like this:
before:
PS! Manually flushing is also replaced with autoflush.
using (Stream outputStream = args.Socket.OutputStream.AsStreamForWrite())
{
using (var streamWriter = new StreamWriter(outputStream))
{
await streamWriter.WriteLineAsync(request);
await streamWriter.FlushAsync();
}
}
after:
Stream outputStream = args.Socket.OutputStream.AsStreamForWrite();
var streamWriter = new StreamWriter(outputStream);
streamWriter.AutoFlush = true;
await streamWriter.WriteLineAsync(request);
Hope it helps someone someday.

How to gracefully close a two-way WebSocket in .Net

I have a WebSocket server that accepts a stream of binary data from a client and responds with another stream of text data for every 4MB read. The server uses IIS 8 and asp.net web api.
Server
public class WebSocketController : ApiController
{
public HttpResponseMessage Get()
{
if (!HttpContext.Current.IsWebSocketRequest)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
HttpContext.Current.AcceptWebSocketRequest(async (context) =>
{
try
{
WebSocket socket = context.WebSocket;
byte[] requestBuffer = new byte[4194304];
int offset = 0;
while (socket.State == WebSocketState.Open)
{
var requestSegment = new ArraySegment<byte>(requestBuffer, offset, requestBuffer.Length - offset);
WebSocketReceiveResult result = await socket.ReceiveAsync(requestSegment, CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close)
{
// Send one last response before closing
var response = new ArraySegment<byte>(Encoding.UTF8.GetBytes("Server got " + offset + " bytes\n"));
await socket.SendAsync(response, WebSocketMessageType.Text, true, CancellationToken.None);
// Close
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
break;
}
offset += result.Count;
if (offset == requestBuffer.Length)
{
// Regular response
var response = new ArraySegment<byte>(Encoding.UTF8.GetBytes("Server got 4194304 bytes\n"));
await socket.SendAsync(response, WebSocketMessageType.Text, true, CancellationToken.None);
offset = 0;
}
}
}
catch (Exception ex)
{
// Log and continue
}
});
return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
}
}
The c# client uses the ClientWebSocket class to connect to the server and send requests. It creates a task for receiving responses from the server that runs in parallel with the request sending. When it is done sending the requests it calls CloseAsync on the socket and then waits for the Receive task to complete.
Client
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace WebSocketClient
{
class Program
{
static void Main(string[] args)
{
try
{
CallWebSocketServer().Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
static async Task CallWebSocketServer()
{
using (ClientWebSocket socket = new ClientWebSocket())
{
await socket.ConnectAsync(new Uri("ws://localhost/RestWebController"), CancellationToken.None);
byte[] buffer = new byte[128 * 1024];
Task receiveTask = Receive(socket);
for (int i = 0; i < 1024; ++i)
{
await socket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Binary, true, CancellationToken.None);
}
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
receiveTask.Wait();
Console.WriteLine("All done");
}
}
static async Task Receive(ClientWebSocket socket)
{
try
{
byte[] recvBuffer = new byte[64 * 1024];
while (socket.State == WebSocketState.Open)
{
var result = await socket.ReceiveAsync(new ArraySegment<byte>(recvBuffer), CancellationToken.None);
Console.WriteLine("Client got {0} bytes", result.Count);
Console.WriteLine(Encoding.UTF8.GetString(recvBuffer, 0, result.Count));
if (result.MessageType == WebSocketMessageType.Close)
{
Console.WriteLine("Close loop complete");
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception in receive - {0}", ex.Message);
}
}
}
}
The problem is that the client blocks at the CloseAsync call.
What would be the correct way of gracefully closing the WebSocket in this scenario?
Figured this out.
Server
Basically, I had to call the ClientWebSocket.CloseOutputAsync (instead of the CloseAsync) method to tell the framework no more output is going to be sent from the client.
await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
Client
Then in the Receive function, I had to allow for socket state WebSocketState.CloseSent to receive the Close response from the server
static async Task Receive(ClientWebSocket socket)
{
try
{
byte[] recvBuffer = new byte[64 * 1024];
while (socket.State == WebSocketState.Open || socket.State == WebSocketState.CloseSent)
{
var result = await socket.ReceiveAsync(new ArraySegment<byte>(recvBuffer), CancellationToken.None);
Console.WriteLine("Client got {0} bytes", result.Count);
Console.WriteLine(Encoding.UTF8.GetString(recvBuffer, 0, result.Count));
if (result.MessageType == WebSocketMessageType.Close)
{
Console.WriteLine("Close loop complete");
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception in receive - {0}", ex.Message);
}
}
i suggest you to look at these links:
asynchronous server:
https://msdn.microsoft.com/en-us/library/fx6588te%28v=vs.110%29.aspx
asynchronous client:
https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx
recently i implementled something similar with these links as an example. the methods "BeginReceive" (for server) and "BeginConnect" (for client) start each a new thread. so there won't be anything that blocks

Categories

Resources