C#网页版+客户端版聊天软件源码分享(C#+长连接+Sqllite数据库实现)
今天我给大家分享一个聊天程序的源码。
网页版加客户端版并存,可以互通
我相信对大家学习和扩展这一块知识是很有用的。
我们先来看下软件结构
一个Web版一个网页版,而客户端是连接的网页的
http://localhost:53947/wwwroot/Lesktop
这个路径
http://localhost:53947/wwwroot/这一部分是网页的地址,大家可以根据自己配置情况进行修改
然后浏览一下Default.aspx页面如下
这是负面版的,客户端的也是一样的,我们先来注册 一个账户
在这里我们注册两个账户还有一个是text用来聊天对话使用
注册的方法是一样的我就不多说了。
下面登录第一个账户看看
这是登录后的效果。
单击聊天室
然后我们再登录另外一个账户text
好了大家应该能看到效果了吧。
然后咱们再发个“你好”
收到了吧,再回复一个
对就是这个效果,
再来看看桌面版的
刚才的消息都在
这是桌面版的效果。
大家感觉怎么样。
我感觉大家可以在这个基础之上进行扩展,最少可以看看他的实现思路
源码分享给大家了只有年费会员或者以上才可以下载
sufeinet.com即时通信_云骞.zip
(3.25 MB, 下载次数: 1950)
ReceiveResponsesHandler 类,这个主要是用来接收和维护长连接的
实现长连接的两个重要来代码预览
[C#] 纯文本查看 复制代码 using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Web;
using System.Xml;
using System.Threading;
namespace Core
{
public class ReceiveResponsesHandler : IHttpAsyncHandler
{
public ReceiveResponsesHandler()
{
}
HttpContext m_Context = null;
IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
{
m_Context = context;
string sessionId = context.Request.Params["SessionID"];
string clientVersion = context.Request.Params["ClientVersion"];
string serverVersion = context.Request.Params["ServerVersion"];
ResponsesListener asyncResult = new ResponsesListener(sessionId, cb, extraData);
try
{
if (serverVersion != ServerImpl.Instance.Version) throw new IncompatibleException();
if (!String.IsNullOrEmpty(clientVersion) && clientVersion != "1.0.1.7") throw new IncompatibleException();
string username = ServerImpl.Instance.GetUserName(context);
if (string.IsNullOrEmpty(username)) throw new UnauthorizedException();
AccountState state = SessionManagement.Instance.GetAccountState(username);
if (state.Receive(sessionId, asyncResult))
{
ThreadPool.QueueUserWorkItem(asyncResult.Complete);
}
}
catch (Exception ex)
{
asyncResult.Cache(Utility.RenderHashJson("IsSucceed", false, "Exception", ex));
ThreadPool.QueueUserWorkItem(asyncResult.Complete);
}
return asyncResult;
}
void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
{
//将消息发送到客户端
ResponsesListener asyncResult = result as ResponsesListener;
asyncResult.Send(m_Context);
}
void IHttpHandler.ProcessRequest(HttpContext context)
{
}
bool IHttpHandler.IsReusable
{
get { return true; }
}
}
class UnauthorizedException : Exception
{
}
class IncompatibleException : Exception
{
}
}
SendCommandHandler是用来发送消息的
[C#] 纯文本查看 复制代码 using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Web;
using System.Xml;
using System.Threading;
using System.Web.SessionState;
using System.Reflection;
namespace Core
{
public class SendCommandHandler : IHttpHandler
{
void IHttpHandler.ProcessRequest(HttpContext context)
{
Exception error = null;
String data = null;
try
{
System.IO.Stream inputStream = context.Request.InputStream;
Byte[] buffer = new Byte[inputStream.Length];
inputStream.Read(buffer, 0, (int)inputStream.Length);
string content = context.Request.ContentEncoding.GetString(buffer);
XmlDocument doc = new XmlDocument();
doc.LoadXml(content);
String[] handlerInfo = doc.DocumentElement.GetAttribute("Handler").Split(new char[] { ' ' });
String cmdId = doc.DocumentElement.GetAttribute("ID");
String sessionId = doc.DocumentElement.GetAttribute("SessionID");
bool isAsyn = Boolean.Parse(doc.DocumentElement.GetAttribute("IsAsyn"));
Assembly assembly = Assembly.Load(handlerInfo[0]);
Type handlerType = assembly.GetType(handlerInfo[1]);
ConstructorInfo ctor = handlerType.GetConstructor(new Type[] { typeof(HttpContext), typeof(String), typeof(String), typeof(String) });
CommandHandler handler = ctor.Invoke(new object[] { context, sessionId, cmdId, doc.DocumentElement.InnerXml }) as CommandHandler;
if (isAsyn)
{
ThreadPool.QueueUserWorkItem(handler.Process);
}
else
{
data = handler.Process();
}
}
catch (Exception ex)
{
error = ex;
}
if (error == null)
{
context.Response.Write(Utility.RenderHashJson("IsSucceed", true, "Data", new JsonText(data)));
}
else
{
context.Response.Write(Utility.RenderHashJson("IsSucceed", false, "Exception", error));
}
}
bool IHttpHandler.IsReusable
{
get { return true; }
}
}
public abstract class CommandHandler
{
HttpContext _context = null;
public HttpContext Context
{
get { return _context; }
}
String _data;
public String Data
{
get { return _data; }
}
String _id;
public String CommandID
{
get { return _id; }
}
String _sessionId;
public String SessionID
{
get { return _sessionId; }
}
public String UserName
{
get { return ServerImpl.Instance.GetUserName(_context); }
}
public CommandHandler(HttpContext context, String sessionId, String id, String data)
{
_context = context;
_data = data;
_id = id;
_sessionId = sessionId;
}
public abstract void Process(object data);
public abstract String Process();
}
}
大家想看对应关系直接看Webconfig文件
[C#] 纯文本查看 复制代码 <?xml version="1.0" encoding="utf-8"?>
<!--
注意: 除了手动编辑此文件以外,您还可以使用 Web 管理工具来
配置应用程序的设置。
可以使用 Visual Studio 中的“网站”->“Asp.Net 配置”选项。
设置和注释的完整列表在 machine.config.comments 中,
该文件通常位于
\Windows\Microsoft.Net\Framework\v2.x\Config 中
-->
<configuration>
<appSettings>
<add key="FileRoot" value="Files"/>
<add key="DefaultPage" value="/Lesktop/Default.aspx"/>
</appSettings>
<connectionStrings/>
<system.web>
<httpHandlers>
<add path="response.aspx" verb="*" type="Core.ReceiveResponsesHandler"/>
<add path="command.aspx" verb="*" type="Core.SendCommandHandler"/>
<add path="download.aspx" verb="*" type="Core.Web.DownloadHandler"/>
<add path="sendfile.aspx" verb="*" type="Core.Web.SendFileHandler"/>
<add path="Config.js.aspx" verb="*" type="Core.Web.DownloadJsHandler"/>
<add path="Embed.js.aspx" verb="*" type="Core.Web.DownloadJsHandler"/>
<add path="headimg.aspx" verb="*" type="Core.Web.DownloadHandler"/>
</httpHandlers>
</system.web>
</configuration>
这样写的目的和好处大家要吧看我的文章
http://www.sufeinet.com/thread-7784-1-1.html
好了就到这里吧,大家有什么问题回复我吧。
感觉还可以的就给你支持
|