Ray*_*Ray 16 .net c# websocket
我想用System.Net.WebSockets.NET 4.5及更高版本的新类(在Windows 8.1上)实现一个简单的聊天服务器.但是,我只找到在ASP.NET环境中使用这些类的示例(特别是这里的那些:http://www.codemag.com/Article/1210051)
我没有这样的,并且希望尽可能地将websocket服务器实现为"原始",但不必重新实现所有的websocket协议,因为Microsoft希望已经在.NET 4.5中实现了这一点.
我想简单地实例化一个新WebSocket类,就像我用普通法做的那样Socket,但构造函数是受保护的.所以我去创建一个继承自它的类,但后来我注意到我必须实现如此多的抽象方法和属性,看起来我正在重写整个逻辑(特别是因为我必须实现像Stateor 这样的东西SendAsync).
我担心MSDN文档没有帮助我.那里的文档有预发布状态,许多评论只是说"TBD"或"实施时".
Ian*_*dby 12
是.
最简单的方法是使用HTTPListener.如果你搜索HTTPListener WebSocket,你会发现很多例子.
简而言之(伪代码)
HttpListener httpListener = new HttpListener();
httpListener.Prefixes.Add("http://localhost/");
httpListener.Start();
HttpListenerContext context = await httpListener.GetContextAsync();
if (context.Request.IsWebSocketRequest)
{
HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(null);
WebSocket webSocket = webSocketContext.WebSocket;
while (webSocket.State == WebSocketState.Open)
{
await webSocket.SendAsync( ... );
}
}
Run Code Online (Sandbox Code Playgroud)
需要.NET 4.5和Windows 8或更高版本.
我只是偶然发现了这个链接,它显示了如何IHttpHandler使用实现来System.Net.WebSockets实现.由于.NET WebSocket实现依赖于IIS 8+,因此需要处理程序.
using System;
using System.Web;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net.WebSockets;
namespace AspNetWebSocketEcho
{
public class EchoHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
context.AcceptWebSocketRequest(HandleWebSocket);
else
context.Response.StatusCode = 400;
}
private async Task HandleWebSocket(WebSocketContext wsContext)
{
const int maxMessageSize = 1024;
byte[] receiveBuffer = new byte[maxMessageSize];
WebSocket socket = wsContext.WebSocket;
while (socket.State == WebSocketState.Open)
{
WebSocketReceiveResult receiveResult = await socket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
if (receiveResult.MessageType == WebSocketMessageType.Close)
{
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
}
else if (receiveResult.MessageType == WebSocketMessageType.Binary)
{
await socket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "Cannot accept binary frame", CancellationToken.None);
}
else
{
int count = receiveResult.Count;
while (receiveResult.EndOfMessage == false)
{
if (count >= maxMessageSize)
{
string closeMessage = string.Format("Maximum message size: {0} bytes.", maxMessageSize);
await socket.CloseAsync(WebSocketCloseStatus.MessageTooLarge, closeMessage, CancellationToken.None);
return;
}
receiveResult = await socket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer, count, maxMessageSize - count), CancellationToken.None);
count += receiveResult.Count;
}
var receivedString = Encoding.UTF8.GetString(receiveBuffer, 0, count);
var echoString = "You said " + receivedString;
ArraySegment<byte> outputBuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(echoString));
await socket.SendAsync(outputBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
}
public bool IsReusable
{
get { return true; }
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望它有所帮助!
Ian的回答肯定很好,但是我需要一个循环过程。互斥锁是我的关键。这是基于他的.net核心2示例。我不能说这个循环的可扩展性。
using System;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
namespace WebSocketServerConsole
{
public class Program
{
static HttpListener httpListener = new HttpListener();
private static Mutex signal = new Mutex();
public static void Main(string[] args)
{
httpListener.Prefixes.Add("http://localhost:8080/");
httpListener.Start();
while (signal.WaitOne())
{
ReceiveConnection();
}
}
public static async System.Threading.Tasks.Task ReceiveConnection()
{
HttpListenerContext context = await
httpListener.GetContextAsync();
if (context.Request.IsWebSocketRequest)
{
HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(null);
WebSocket webSocket = webSocketContext.WebSocket;
while (webSocket.State == WebSocketState.Open)
{
await webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes("Hello world")),
WebSocketMessageType.Text, true, CancellationToken.None);
}
}
signal.ReleaseMutex();
}
}
}
Run Code Online (Sandbox Code Playgroud)
并为其提供测试html页面。
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var wsUri = "ws://localhost:8080/";
var output;
function init()
{
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket()
{
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt)
{
writeToScreen("DISCONNECTED");
}
function onMessage(evt)
{
writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
websocket.close();
}
function onError(evt)
{
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message)
{
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message)
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19501 次 |
| 最近记录: |