using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.WebSockets;
namespace WebSocketEcho
{
///
/// Echo 的摘要说明
///
public class Echo : IHttpHandler
{
// list of client WebSockets that are open
private static readonly IList Clients = new List();
// ensure thread-safety of the WebSocket clients
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
context.AcceptWebSocketRequest(ProcessSocketRequest);
}
private async Task ProcessSocketRequest(AspNetWebSocketContext context)
{
var socket = context.WebSocket;
// add socket to socket list
Locker.EnterWriteLock();
try
{
Clients.Add(socket);
}
finally
{
Locker.ExitWriteLock();
}
// maintain socket
while (true)
{
var array = new byte[1024];
var buffer = new ArraySegment(array);
// async wait for a change in the socket
var result = await socket.ReceiveAsync(buffer, CancellationToken.None);
if (socket.State == WebSocketState.Open)
{
// echo to all clients
foreach (var client in Clients)
{
var seg = new ArraySegment(array, 0, result.Count);
await client.SendAsync(seg, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
else
{
// client is no longer available - delete from list
Locker.EnterWriteLock();
try
{
Clients.Remove(socket);
}
finally
{
Locker.ExitWriteLock();
}
break;
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}