WebSocket,IsWebSocketRequest与AspNetWebSocketContext
asp.net新建一个服务端程序,用来处理链接服务端:
1,新建一个处理程序 .ashx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.WebSockets;
using SFellowEntity.Models; namespace SchoolfellowCard.Handler
{
/// <summary>
/// WebSocketServer webSocket服务
/// </summary>
public class WebSocketServer : IHttpHandler
{
//用户连接池
private static Dictionary<string, WebSocket> connectPool = new Dictionary<string, WebSocket>();
//离线消息池
private static Dictionary<string, List<MessageInfo>> messagePool = new Dictionary<string, List<MessageInfo>>(); public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(ProcessChat);
}
}
/// <summary>
/// webSocket异步作业
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private async Task ProcessChat(AspNetWebSocketContext context)
{
//WebSocket socket = context.WebSocket;
//while (true)
//{
// if (socket.State == WebSocketState.Open)
// {
// ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
// WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
// string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
// userMsg = "你发送了:" + userMsg + "于" + DateTime.Now.ToLongTimeString();
// buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
// await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
// }
// else
// {
// break;
// }
//}
WebSocket socket = context.WebSocket;
string user =string.Format("{0}", context.QueryString["user"]); try
{
#region 验证用户添加连接池 //第一次open时,添加到连接池中
if (!connectPool.ContainsKey(user))
{
connectPool.Add(user, socket); //不存在,添加
}
else
{
if (socket != connectPool[user]) //当前对象不一致,更新
{
connectPool[user] = socket;
}
} #endregion #region 离线消息处理
if (messagePool.ContainsKey(user))
{
//TODO:离线消息可放入数据库在此获取离线消息并返回给对应的用户
List<MessageInfo> msgs = messagePool[user];
foreach (MessageInfo item in msgs)
{
await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
}
messagePool.Remove(user);//移除离线消息
//TODO:处理完后标记离线消息已推送
}
#endregion string descUser = string.Empty;//目的用户
while (true)
{
if (socket.State == WebSocketState.Open)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
//websocket接收消息
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None); #region 消息处理(字符截取、消息转发)
try
{
#region 关闭Socket处理,删除连接池
if (socket.State != WebSocketState.Open)//连接关闭
{
if (connectPool.ContainsKey(user)) connectPool.Remove(user);//删除连接池
break;
}
#endregion string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
string[] msgList = userMsg.Split('|');
if (msgList.Length == 2)
{
if (msgList[0].Trim().Length > 0)
descUser = msgList[0].Trim();//记录消息目的用户//TODO:将消息接收者可放入数据库存贮记录
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
}
else
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg)); if (connectPool.ContainsKey(descUser))//判断客户端是否在线
{
WebSocket destSocket = connectPool[descUser];//目的客户端
if (destSocket != null && destSocket.State == WebSocketState.Open)
await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
else
{
Task.Run(() =>
{
if (!messagePool.ContainsKey(descUser))//将用户添加至离线消息池中
messagePool.Add(descUser, new List<MessageInfo>());
messagePool[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
//TODO:离线消息插入数据库
});
}
}
catch (Exception exs)
{
//消息转发异常处理,本次消息忽略 继续监听接下来的消息
}
#endregion
}
else
{
break;
}
}//while end
}
catch (Exception ex)
{
//整体异常处理
if (connectPool.ContainsKey(user)) connectPool.Remove(user);
}
} public bool IsReusable
{
get
{
return false;
}
}
}
}
其中,MessageInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace SFellowEntity.Models
{
/// <summary>
/// 消息
/// </summary>
public class MessageInfo
{
/// <summary>
/// 消息内容
/// </summary>
public ArraySegment<byte> MsgContent { get; set; }
/// <summary>
/// 消息时间
/// </summary>
public DateTime MsgTime { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="msgTime"></param>
/// <param name="msgContent"></param>
public MessageInfo(DateTime msgTime, ArraySegment<byte> msgContent)
{
MsgTime = msgTime;
MsgContent = msgContent;
}
}
}
页面端:
2,页面JavaScript创建WebSocket对象,并发起连接
$('#conn').click(function () {
ws = new WebSocket('ws://' + window.location.hostname + ':' + window.location.port + '/Handler/WebSocketServer.ashx?user=' + $("#user").val());
$('#msg').append('<p>正在连接</p>');
ws.onopen = function () {
$('#msg').append('<p>已经连接</p>');
}
ws.onmessage = function (evt) {
$('#msg').append('<p>' + evt.data + '</p>');
}
ws.onerror = function (evt) {
$('#msg').append('<p>' + JSON.stringify(evt) + '</p>');
}
ws.onclose = function () {
$('#msg').append('<p>已经关闭</p>');
}
});
$('#close').click(function () {
ws.close();
});
$('#send').click(function () {
if (ws.readyState == WebSocket.OPEN) {
ws.send($("#to").val() + "|" + $('#content').val());
}
else {
$('#tips').text('连接已经关闭');
}
});
WebSocket,IsWebSocketRequest与AspNetWebSocketContext的更多相关文章
- .net使用websocket
专业挖坑21年 1.前 言 网上找了很多资料,可能是自己找的路子不对吧,都找不到适合我这样萌新的文章,大多.net环境使用的websocket都是在说一个通信的案例,学起来的确很吃力,自己也挖 ...
- websocket在.net4.5中实现的简单demo
以下代码环境要求:win8或win10, .net4.5+IIS8 win7上是IIS7,win7上.net本身不直接支持websocket, win7可以用superwebsocket, 或自己根据 ...
- WebSocket在ASP.NET MVC4中的简单实现 (该文章转自网络,经尝试并未实现,请大神指点。)
WebSocket 规范的目标是在浏览器中实现和服务器端双向通信.双向通信可以拓展浏览器上的应用类型,例如实时的数据推送.游戏.聊天等.有了WebSocket,我们就可以通过持久的浏览器和服务器的连接 ...
- WebSocket在ASP.NET MVC4中的简单实现
WebSocket在ASP.NET MVC4中的简单实现 2013-12-21 20:48 by 小白哥哥, 810 阅读, 3 评论, 收藏, 编辑 WebSocket 规范的目标是在浏览器中实现和 ...
- HTTP协议系列(3)---包括WebSocket简单介绍
一.HTTPS HTTP是超文本传输协议,那HTTPS是什么尼?要明白HTTPS是什么先要明白HTTP的缺点,想一下我们在使用HTTP的时候会有那些缺点尼? 1.通信使用的明文(不加密),内容 ...
- .NET 即时通信,WebSocket服务端实例
即时通信常用手段 1.第三方平台 谷歌.腾讯 环信等多如牛毛,其中谷歌即时通信是免费的,但免费就是免费的并不好用.其他的一些第三方一般收费的,使用要则限流(1s/限制x条消息)要么则限制用户数. 但稳 ...
- 第一节:.Net版基于WebSocket的聊天室样例
一. 说在前面的话 该篇文章为实时通讯系列的第一节,基于WebSocket编写了一个简易版聊天样例,主要作用是为引出后面SignalR系列的用法及其强大方便之处,通过这个样例与后续的SignalR对比 ...
- 【WebSocket No.3】使用WebSocket协议来做服务器
写在开始 上面一篇写了一篇使用WebSocket做客户端,然后服务端是socke代码实现的.传送门:webSocket和Socket实现聊天群发 本来我是打算写到一章上的,毕竟实现的都是一样的功能,后 ...
- Asp.net+WebSocket+Emgucv实时人脸识别
上个月在网上看到一个用web实现简单AR效果的文章,然后自己一路折腾,最后折腾出来一个 Asp.net+WebSocket+Emgucv实时人脸识别的东西,网上也有不少相关资料,有用winform的也 ...
- WebSocket简单尝试
System.Net.WebSockets.WebSocket 需要.NET 4.5,IIS8以上,Windows Server2008R2自带的IIS不支持,Windows8及Server2012以 ...
随机推荐
- docker新建自定义网桥,实现不同主机容器互联
不同主机间的容器网络互联,网络上的所有教程都是通过open vswitch等虚拟网桥方式实现的,但是最近本人发现可以直接通过配置网桥实现网络的互联,而不用安装配置open vswitch.在这里分享一 ...
- swiper 垂直滚动
<template> <div style="height: 100%;width: 100%;"> <swiper :direction=" ...
- 低功耗4G模组:Air780EP开发板RC522实例
本文讲解合宙Air780EP开发板RC522实例,文末[阅读原文]获取最新资料. 本文档适用于Air780EP开发板 关联文档和使用工具 LuatOS-Soc固件获取 https://gitee. ...
- 一文讲透 FPGA CDC 多bit跨时钟域同步-hand-shanking机制
一.背景 数据的跨时钟域处理是FPGA开发过程中的常见问题,存在两种情况 慢时钟向快时钟同步:只需在快时钟域打两拍即可.其RTL如下: 打拍同步的原理:大家在初学FPGA时,经常听过FPGA中对信号打 ...
- 通过Java代码发送OutLook邮件
准备 我们想通过Java代码实现发送OutLook邮件,必须准备以下材料: OutLook邮箱 目标邮箱 查看OutLook邮箱信息 打开OutLook邮箱,在Settings中搜索或找到SMTP: ...
- 开源IDS/IPS Suricata的部署与使用
目录 前言 在Linux上部署Suricata Suricata的基本配置 配置文件 Suricata的规则 Suricata的使用 Suricata检测SQL注入 前言 Suricata 是一个高性 ...
- 桌面应用开发之Electron
Electron 官网: https://www.electronjs.org/ Electron是一个使用JavaScript.HTML和CSS构建跨平台的桌面应用程序.它基于Node.js和Chr ...
- git针对指定网站设置代理
我们经常要用到各种git地址,比如github.gitee还有自己搭建的git等等. 但是github我们经常拉取和推送代码的时候超时,这时候如果我们搜索会发现大量的文章都是告诉我们设置全局系统代理: ...
- CSS 样式百分比
1.宽高百分比 元素宽度/高度百分比是基于父级元素的width/height,不包含padding,border 注意:高度百分比一定要求父元素有设置height属性,只设置 min-height 虽 ...
- web移动端常见问题(二)
1.input光标颜色 默认情况下,光标颜色与字体颜色color相同,但也可以通过caret-color属性来单独设置 但是IOS的光标与字体颜色无关,默认是蓝色 可以单独设置光标颜色,这样ios也有 ...