wbSocket
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<title></title>
<script src="js/jquery-3.2.1.min.js"></script>
<script>
var ws;
$().ready(function () {
$('#conn').click(function () {
ws = new WebSocket('ws://localhost:4498/test2.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('连接已经关闭');
}
}); });
</script>
</head>
<body>
<div>
<input id="user" type="text" value="xx" />
<input id="conn" type="button" value="连接" />
<input id="close" type="button" value="关闭" /><br />
<span id="tips"></span>
<input id="content" type="text" value="txt" />
<input id="send" type="button" value="发送" /><br />
<input id="to" type="text" value="xx" />目的用户
<div id="msg">
</div>
</div>
</body>
</html>
<%@ WebHandler Language="C#" Class="test2" %> using System;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.WebSockets;
public class test2 : IHttpHandler
{
/// <summary>
/// 离线消息
/// </summary>
public class MessageInfo
{
public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)
{
MsgTime = _MsgTime;
MsgContent = _MsgContent;
}
public DateTime MsgTime { get; set; }
public ArraySegment<byte> MsgContent { get; set; }
} private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池
private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池 public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(ProcessChat);
}
else
{
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff"));
}
} private async Task ProcessChat(AspNetWebSocketContext context)
{
WebSocket socket = context.WebSocket;
string user = context.QueryString["user"].ToString(); try
{
#region 用户添加连接池
//第一次open时,添加到连接池中
if (!CONNECT_POOL.ContainsKey(user))
CONNECT_POOL.Add(user, socket);//不存在,添加
else
if (socket != CONNECT_POOL[user])//当前对象不一致,更新
CONNECT_POOL[user] = socket;
#endregion #region 离线消息处理
if (MESSAGE_POOL.ContainsKey(user))
{
List<MessageInfo> msgs = MESSAGE_POOL[user];
foreach (MessageInfo item in msgs)
{
await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
}
MESSAGE_POOL.Remove(user);//移除离线消息
}
#endregion string descUser = string.Empty;//目的用户
while (true)
{
if (socket.State == WebSocketState.Open)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None); #region 消息处理(字符截取、消息转发)
try
{
#region 关闭Socket处理,删除连接池
if (socket.State != WebSocketState.Open)//连接关闭
{
if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.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();//记录消息目的用户
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
}
else
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg)); if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
{
WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
if (destSocket != null && destSocket.State == WebSocketState.Open)
await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
else
{
Task.Run(() =>
{
if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
MESSAGE_POOL.Add(descUser, new List<MessageInfo>());
MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
});
}
}
catch (Exception exs)
{
//消息转发异常处理,本次消息忽略 继续监听接下来的消息
}
#endregion
}
else
{
break;
}
}//while end
}
catch (Exception ex)
{
//整体异常处理
if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);
}
} public bool IsReusable
{
get
{
return false;
}
} }
http://www.cnblogs.com/cemaster/p/6006510.html
wbSocket的更多相关文章
- PostgreSQL Replication之第十五章 与Walbouncer 一起工作
与Walbouncer 一起工作 在本书的最后一章,将引导您通向2014年发布的一个工具,称为walbouncer.本书中的大多数技巧说明了如何复制整个数据库实例,如何分片,等等.在最后一章,是关于w ...
- WebSocket和kafka实现数据实时推送到前端
一. 需求背景 最近新接触一个需求,需要将kafka中的数据实时推送到前端展示.最开始想到的是前端轮询接口数据,但是无法保证轮询的频率和消费的频率完全一致,或造成数据缺失等问题.最终确定用利 ...
- nodejs+websocket实时聊天系统
介绍下websocket: webSocket协议本质上是一个基于tcp的协议; 建立一个websocket连接,大体的过程: 1.客户端浏览器首先向服务器发起一个http请求,这个请求和平常的请求有 ...
- java kafka单列模式生产者客户端
1.所需要的依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="ht ...
随机推荐
- NIO 选择器 Selector
选择器提供选择执行已经就绪的任务的能力,这使得多元 I/O 成为可能.就像在第一章中描述的那样,就绪选择和多元执行使得单线程能够有效率地同时管理多个 I/O 通道(Channels).C/C++代码的 ...
- B2C电子商务系统研发——商品SKU分析和设计(一)
一.SKU及相关概念定义 在设计商品SKU之前,首先让我们熟悉一下SKU和相关的一些概念. # 什么是SKU: SKU=Stock Keeping Unit(库存量单位) 同一型号的商品,或者说是同一 ...
- php常用命令
--------------------------------------------------------------- 重启phpservice php-fpm restart ------- ...
- PostgreSQL中的Object Identifier(oid)数据类型
PostgreSQL在内部使用对象标识符(OID)作为各种系统表的主键.OID不会添加到用户创建的表中,除非在创建表时指定了WITH OIDS,或者启用了default_with_oids配置变量.类 ...
- IDEA查看接口的实现类
查找接口的实现类: 快捷键 ctrl + alt +B 再按F2查看详细文档注解 查看类或接口的继承关系: ctrl + h
- Python - Django - form 组件校验功能
app01/models.py: from django.db import models class UserInfo(models.Model): username = models.CharFi ...
- datatables:initComplete和drawCallback比较
drawCallback: 对表的每个绘制事件执行操作非常有用 - 例如,您可能希望使用新显示的数据更新外部控件,或者启用服务器端处理,您可能希望将事件分配给新创建的元素.此回调旨在实现此目的,并将在 ...
- [计算机视觉][神经网络与深度学习]Faster R-CNN配置及其训练教程2
faster-rcnn分为matlab版本和python版本,首先记录弄python版本的环境搭建过程.matlab版本见另一篇:faster-rcnn(testing): ubuntu14.04+c ...
- hadoop进阶---hadoop性能优化(一)---hdfs空间不足的管理优化
Hadoop 空间不足,hive首先就会没法跑了,进度始终是0%. 将HDFS备份数降低 将默认的备份数3设置为2. 步骤:CDH–>HDFS–>配置–>搜索dfs.replicat ...
- DHCP的配置方法
1.实验拓扑图: 2.配置命令: AR2: <Huawei>system-view[Huawei]dhcp enable #开启DHCP服务[Huawei]interface G ...