Net Core SignalR 测试,可以用于unity、Layair、白鹭引擎、大数据分析平台等高可用消息实时通信器。

SignalR介绍

SignalR介绍来源于微软文档,不过多解释。https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introduction?view=aspnetcore-2.1

ASP.NET Core SignalR 是一个开源代码库,它简化了向应用添加实时 Web 功能的过程。 实时 Web 功能使服务器端代码能够即时将内容推送到客户端。

SignalR 的适用对象:

  • 需要来自服务器的高频率更新的应用。 例如:游戏、社交网络、投票、拍卖、地图和 GPS 应用。
  • 仪表板和监视应用。 示例包括公司仪表板、销售状态即时更新或行程警示。
  • 协作应用。 协作应用的示例包括白板应用和团队会议软件。
  • 需要通知的应用。 社交网络、电子邮件、聊天、游戏、行程警示以及许多其他应用都使用通知。

以下是 ASP.NET Core SignalR 的一些功能:

  • 自动管理连接。
  • 同时向所有连接的客户端发送消息。 例如,聊天室。
  • 将消息发送到特定的客户端或客户端组。
  • 扩展以处理增加的流量。

以上是SignalR介绍,除了以上说明外还有如下优点:

  • 它可支持各个平台通信。只要可以使用websocket就可以进行连接。
  • 而且进行了大量优化处理,非常方便开发者使用。
  • 拥有自由可扩展性,可通过redis 方式搭建分布式socket通信,支持成千上万人不是梦。
  • 自定义协议,除了json协议外、还支持MessagePack协议。还可以自己定义相关协议进行扩展。
  • 可以用于unity、Layair、白鹭引擎、大数据分析平台等高频率使用消息实时通信器。

SignalR使用

一、  新建项目,新建一个空Asp.net core 网站

Net Core SignalR 测试,可以用于unity、Layair、白鹭引擎、大数据分析平台等高可用消息实时通信器。_第1张图片

二、引用SignalR中间件

1. 创建Hub中间件 HubHelper,及游戏简单处理逻辑类

using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;

/// 
/// 消息中心
/// 
public class HubHelper : Hub
{
    /// 
    /// 游戏逻辑
    /// 
    static GameLogic gameLogic;
    static bool isStart = false;


    /// 
    /// 获取当前用户Id
    /// 
    /// 
    public void GetId(Data data)
    {
        Clients.Caller.SendAsync("GetId", Context.ConnectionId);
    }
    /// 
    /// 获取当前连接所有用户
    /// 
    /// 
    public void GetALLUser(Data data)
    {
        if (gameLogic != null)
            Clients.Caller.SendAsync("GetALLUser", gameLogic.list);
    }
    /// 
    /// 用户状态改变
    /// 
    /// 用户信息
    public void UpdateSate(UserInfo user)
    {
        gameLogic.UpdateUserInfo(Context.ConnectionId, user);
    }
    /// 
    /// 用户加入
    /// 
    /// 
    public void Join(Data data)
    {
        if (!isStart)
        {
            isStart = true;
            gameLogic = new GameLogic(this.Clients.All);
        }
        gameLogic.JoinUser(this.Context.ConnectionId, data);

    }

    /// 
    /// 用户断开
    /// 
    /// 
    /// 
    public override Task OnDisconnectedAsync(Exception exception)
    {
        if (gameLogic != null)
            gameLogic.LevelUser(Context.ConnectionId);
        return base.OnDisconnectedAsync(exception);
    }
}
/// 
/// 游戏逻辑
/// 
public class GameLogic
{
    /// 
    /// 全局客户端通信信息
    /// 
    readonly IClientProxy gloable;
    /// 
    /// 游戏定时器
    /// 
    readonly Timer gameTimer;
    /// 
    /// 所有用户
    /// 
    public List list = new List();

    public GameLogic(IClientProxy _gloable)
    {
        gloable = _gloable;
        //启动模拟游戏帧
        gameTimer = new Timer(30);
        gameTimer.Elapsed += GameTimer_Elapsed;
        gameTimer.Start();
    }

    private void GameTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        for (int i = 0; i < list.Count; i++)
        {
            var item = list[i];
            //发送已改变状态用户信息广播
            if (item.Change)
            {
                item.Change = false; 
                gloable.SendAsync("update", list[i]);
            }
        }
    }
    /// 
    /// 用户加入
    /// 
    /// 用户编号
    /// 加入信息
    public void JoinUser(string id, Data data)
    {
        //随机获取角色图片
        var user = new UserInfo() { Id = id, Name = data.Name, Role = "role" + new Random().Next(1, 4) + ".jpg", Change = true };
        list.Add(user);
        gloable.SendAsync("add", user);
    }
    /// 
    /// 用户断开处理
    /// 
    /// 用户编号
    public void LevelUser(string id)
    {
        var user = list.FirstOrDefault(mm => mm.Id == id);
        if (user != null)
        {
            gloable.SendAsync("level", user);
            list.Remove(user);
        }
    }
    /// 
    /// 更新用户信息
    /// 
    /// 用户编号
    /// 用户信息
    public void UpdateUserInfo(string id, UserInfo changeUser)
    {
        var user = list.FirstOrDefault(mm => mm.Id == id);
        if (user != null)
        {
            user.X = changeUser.X;
            user.Y = changeUser.Y;
            user.Change = true;
        }
    }
}
/// 
///用户信息
/// 
public class UserInfo
{
    public string Id { get; set; }
    /// 
    /// 用户名
    /// 
    public string Name { get; set; }
    /// 
    /// 用户角色图片
    /// 
    public string Role { get; set; }
    public int X { get; set; }
    public int Y { get; set; }
    /// 
    /// 是否动作变化
    /// 
    public bool Change { get; set; }
}
/// 
/// 传输数据
/// 
public class Data
{
    public string Name { get; set; }
    public string Value { get; set; }
}

 

2. 注册SignalR中间件,注册文件浏览。

    public class Startup
    {
        
        public void ConfigureServices(IServiceCollection services)
        { 
            services.AddSignalR();
        }
         
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseDefaultFiles().UseStaticFiles(); 
            app.UseSignalR(router => {
                router.MapHub("/game");
            });
        }
    }

三、前端代码部分

1.实现 MSGGame.js 游戏消息处理js, 重写原因是:无代码提示,而且重写后方便自己扩展增加功能和相关管理。NetCore SingalR无重连功能,需要自己实现。

//消息处理
var MSG = {
    isStart: false,
    connection: null,

    /**
     * 初始化信息处理 返回promis
     * @param {string} _url 消息地址
     * @param {Function} _func 相关绑定函数
     */
    init: function (url) {
        if (url == null)
            url = "/game";
        MSG.connection = new signalR.HubConnectionBuilder().withUrl(url).build(); 
    },
    /**
     * 注册监听函数
     * @param {any} key 监听键名
     * @param {any} func 监听执行函数
     */
    reg: function (key,func) {
        MSG.connection.on(key, function (result) {
            func(result);
        });
    },
    /**启动消息 返回promis*/
    start: function () {
        if (MSG.isStart) {
            return;
        }
        MSG.isStart = true;
        var _result = MSG.connection.start();
        _result.then(function (_return) {

        }).catch(function (err) {
            MSG.isStart = false;
            return console.error(err.toString());
        });
        return _result;
    },

   /**
    * 停止消息 返回promis
    * */
    stop: function () {
        if (!MSG.isStart) {
            return;
        }
        var _result = MSG.connection.stop();
        _result.then(function (_return) {

        }).catche(function (err) {

        });
        MSG.isStart = false;
        return _result;
    }, 
    /**
     * 
     * @param {any} api
     * @param {any} msg
     */
    send: function (api, msg) {
        if (!MSG.isStart) {
            return;
        }
        var _result = MSG.connection.invoke(api, msg);
        //回调处理
        _result.then(function (_return) {

        });
        //错误处理
        _result.catch(function (_error) {

        });
        return _result;
    },
    /**重新连接 未实现
     *@param  {number} num 尝试连接次数
     */
    reconnection: function (num) {
        if (MSG.isStart) {

        }
    }
}; 

 

2.在wwwroot下建立index.html 然后编写简单逻辑




    "utf-8" />
    
    



    
"clone_role" class="role" style="display: none;">

克隆对象

"role1.jpg" />
"text" name="name" id="userName" placeholder="你的名称!" />
"content"> 输入名称,点击开始进行测试。随后随便点击屏幕。

 3. 最终目录结构为:

Net Core SignalR 测试,可以用于unity、Layair、白鹭引擎、大数据分析平台等高可用消息实时通信器。_第2张图片

 

四、运行测试,打开多个网页。输入相关名称。然后点击屏幕。看看是否能联动。 可以发给自己好朋友测测看看。

Net Core SignalR 测试,可以用于unity、Layair、白鹭引擎、大数据分析平台等高可用消息实时通信器。_第3张图片

 

五、Signalr问题说明、相关建议经验

1.Signalr 发布到 winserver 2008R2 时 无法使用websocket通信,需要进行特殊处理。

2.对于实时性要求非常高时,没有进行高并发处理过。希望处理过的人,通知我下。

3.我这有白鹭引擎、Layaair 连接Signalr 的TS代码, 也有unity 连接 net core Signalr 代码(因 unity  我用时只提供了 老版本连接方法,现在没去看是否有新可用的), 需要的可以联系我。

4. Net Core 开源后,群众呼声很高。无论是机器学习、微服务方面 微软都在逐步大力支持中, 希望大家共同努力让.Net 这么好用的东西 走得更远。

5.曾经不写博客什么的感觉没用,不过眼看.net 人员越来越少。    感叹!

6.如果想实现分布式的可参考官网,自己动手丰衣足食。

以上仅供娱乐测试。代码地址:https://github.com/840900649/SignalRTest

 

你可能感兴趣的:(Net Core SignalR 测试,可以用于unity、Layair、白鹭引擎、大数据分析平台等高可用消息实时通信器。)