110,534
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
using System.Threading;
using fastCSharp.setup.cSharp;
using fastCSharp.threading;
namespace fastCSharp.demo.chatServer
{
/// <summary>
/// 服务端
/// </summary>
[fastCSharp.setup.cSharp.tcpServer(IsIdentityCommand = true, IsAsynchronous = true, Host = "127.0.0.1", Port = 12345)]
public partial class server
{
/// <summary>
/// 命令枚举
/// </summary>
private enum command
{
/// <summary>
/// 登陆
/// </summary>
Login,
/// <summary>
/// 退出
/// </summary>
Logout,
/// <summary>
/// 获取用户列表
/// </summary>
GetUsers,
/// <summary>
/// 发送消息
/// </summary>
Send,
/// <summary>
/// 接收消息
/// </summary>
Receive,
}
/// <summary>
/// 用户信息
/// </summary>
private sealed class userInfo
{
/// <summary>
/// 用户名
/// </summary>
public string User;
/// <summary>
/// 用户版本
/// </summary>
public int UserVersion = int.MinValue;
/// <summary>
/// 获取用户列表委托
/// </summary>
public action<asynchronousMethod.returnValue<usersVerison>> OnUserChanged;
/// <summary>
/// 用户消息集合
/// </summary>
public list<message> Messages = new list<message>();
/// <summary>
/// 获取消息委托
/// </summary>
public action<asynchronousMethod.returnValue<message[]>> OnMessage;
}
/// <summary>
/// 用户集合
/// </summary>
private Dictionary<string, userInfo> users = new Dictionary<string, userInfo>();
/// <summary>
/// 用户集合访问锁
/// </summary>
private int userLock;
/// <summary>
/// 用户版本
/// </summary>
private int userVersion;
/// <summary>
/// 用户登陆
/// </summary>
public event action<string> OnLogin;
/// <summary>
/// 用户登陆
/// </summary>
/// <param name="client">客户端标识</param>
/// <param name="user"></param>
/// <returns></returns>
[fastCSharp.setup.cSharp.tcpServer(CommandIentity = (int)command.Login)]
private bool login(tcpBase.client client, string user)
{
if (user.length() != 0)
{
if (userChangeHandle == null) userChangeHandle = userChange;
interlocked.CompareSetSleep0(ref userLock);
try
{
if (!users.ContainsKey(user))
{
users.Add(user, new userInfo { User = user });
client.UserInfo = user;
++userVersion;
task.TinyTask.Add(userChangeHandle, user);
return true;
}
}
finally { userLock = 0; }
}
return false;
}
/// <summary>
/// 用户退出
/// </summary>
public event action<string> OnLogout;
/// <summary>
/// 退出
/// </summary>
/// <param name="client"></param>
[fastCSharp.setup.cSharp.tcpServer(CommandIentity = (int)command.Logout)]
private void logout(tcpBase.client client)
{
string user = (string)client.UserInfo;
userInfo userInfo;
interlocked.CompareSetSleep0(ref userLock);
try
{
if (users.TryGetValue(user, out userInfo)) users.Remove(user);
++userVersion;
}
finally { userLock = 0; }
if (userInfo != null)
{
if (userChangeHandle == null) userChangeHandle = userChange;
task.TinyTask.Add(userChangeHandle, null);
if (userInfo.OnUserChanged != null) userInfo.OnUserChanged(new usersVerison { UserVersion = int.MinValue });
if (userInfo.OnMessage != null) userInfo.OnMessage(userInfo.Messages.toArray());
if (OnLogout != null) task.TinyTask.Add(OnLogout, user);
}
}
/// <summary>
/// 用户列表与版本信息
/// </summary>
[fastCSharp.setup.cSharp.serialize(IsBaseSerialize = true)]
public partial struct usersVerison
{
/// <summary>
/// 用户列表
/// </summary>
public string[] Users;
/// <summary>
/// 用户列表版本
/// </summary>
public int UserVersion;
}
/// <summary>
/// 获取用户列表
/// </summary>
/// <param name="client"></param>
/// <param name="userVersion"></param>
/// <param name="onUserChanged"></param>
[fastCSharp.setup.cSharp.tcpServer(CommandIentity = (int)command.GetUsers, IsAsynchronousCallback = true, IsClientAsynchronous = true, IsClientSynchronous = false)]
private void getUsers(tcpBase.client client, int userVersion, action<asynchronousMethod.returnValue<usersVerison>> onUserChanged)
{
usersVerison usersVerison = new usersVerison();
action<asynchronousMethod.returnValue<usersVerison>> oldOnUserChanged = null;
interlocked.CompareSetSleep0(ref userLock);
try
{
userInfo userInfo;
if (users.TryGetValue((string)client.UserInfo, out userInfo))
{
if (this.userVersion == userVersion)
{
oldOnUserChanged = userInfo.OnUserChanged;
userInfo.OnUserChanged = onUserChanged;
userInfo.UserVersion = userVersion;
onUserChanged = null;
}
else
{
usersVerison.Users = users.Keys.getArray();
usersVerison.UserVersion = this.userVersion;
}
}
else
{
oldOnUserChanged = onUserChanged;
onUserChanged = null;
}
}
finally
{
userLock = 0;
if (onUserChanged != null) onUserChanged(usersVerison);
if (oldOnUserChanged != null) oldOnUserChanged(new usersVerison { UserVersion = int.MinValue });
}
}
/// <summary>
/// 获取用户列表委托集合
/// </summary>
private list<action<asynchronousMethod.returnValue<usersVerison>>> onUserChangeds = new list<action<asynchronousMethod.returnValue<usersVerison>>>();
/// <summary>
/// 获取用户列表委托集合访问锁
/// </summary>
private int onUserChangedLock;
/// <summary>
/// 用户列表更新
/// </summary>
private action<string> userChangeHandle;
/// <summary>
/// 用户列表更新
/// </summary>
/// <param name="user">新增用户名</param>
private void userChange(string user)
{
usersVerison usersVerison = new usersVerison { UserVersion = int.MinValue };
while (userVersion != usersVerison.UserVersion && Interlocked.CompareExchange(ref onUserChangedLock, 1, 0) == 0)
{
try
{
interlocked.CompareSetSleep0(ref userLock);
try
{
usersVerison.Users = users.Keys.getArray();
usersVerison.UserVersion = userVersion;
foreach (userInfo userInfo in users.Values)
{
if (userInfo.UserVersion != userVersion && userInfo.OnUserChanged != null)
{
onUserChangeds.Add(userInfo.OnUserChanged);
userInfo.OnUserChanged = null;
}
}
}
finally { userLock = 0; }
while (userVersion == usersVerison.UserVersion && onUserChangeds.Count != 0)
{
try
{
onUserChangeds.Pop()(usersVerison);
}
catch { }
}
}
finally { onUserChangedLock = 0; }
}
if (user != null && OnLogin != null) OnLogin(user);
}
/// <summary>
/// 消息
/// </summary>
[fastCSharp.setup.cSharp.serialize(IsBaseSerialize = true)]
public partial struct message
{
/// <summary>
/// 发送者
/// </summary>
public string User;
/// <summary>
/// 发送时间
/// </summary>
public DateTime Time;
/// <summary>
/// 发送内容
/// </summary>
public string Message;
}
/// <summary>
/// 发送消息
/// </summary>
public event action<message> OnMessage;
未完待续