使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端

SignalR 是一个开源的服务端与客户端实现实时通讯的插件,更据微软asp.net core 文档解释如下:

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第1张图片

服务端:

使用的是 asp.net core3.1,在Startup.cs 的配置服务的方法里添加services.AddSignalR();

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第2张图片

 

然后在Configure 方法里配置路由

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第3张图片

图片箭头指向的字符串是到时候客户端请求使用的的路径

创建一个类 HubUtil.cs此类用来实现接收来在客户端消息和发送消息给客户端功能

该类继承Hub。

 

 

 

 

public class ChatHub : Hub

{

    public Task SendMessage(string user, string message)

    {

        return Clients.All.SendAsync("ReceiveMessage", user, message);

    }

}

一个简单的服务端就完成了

附上微软文档的详细属性和方法说明:

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第4张图片

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第5张图片

强类型:

使用的缺点 SendAsync 是它依赖于幻字符串来指定要调用的客户端方法。 如果客户端中的方法名称拼写错误或缺失,则这会使代码对运行时错误开放。

使用的替代方法 SendAsync 是使用强类型 Hub Hub  在下面的示例中, ChatHub 客户端方法已提取到名为的接口 IchatClient(官方文档解释)

public interface ICommonClient

{

    /// 

        /// 测试用

        /// 

        /// 

        /// 

        /// 

        Task ReceiveMessage(string user, string message);



        /// 

        /// 添加连接客户端

        /// 

        /// 

        /// 

        Task AddClient(MoHubUser user);



        /// 

        /// 获取连接客户端人数

        /// 

        /// 

        /// 

        Task GetClientCount(int count);}

public class StronglyTypedChatHub : Hub

{

    public async Task SendMessage(string user, string message)

    {

        await Clients.All.ReceiveMessage(user, message);

    }



    public Task SendMessageToCaller(string message)

    {

        return Clients.Caller.ReceiveMessage(message);

    }

}

处理连接事件

#region SignalR中心 API 提供 OnConnectedAsync 和 OnDisconnectedAsync 虚拟方法来管理和跟踪连接。

        /// 

        /// 处理连接事件

        /// 重写 OnConnectedAsync 虚拟方法,以便在客户端连接到集线器时执行操作,如将其添加到组。

        /// 

        /// 

        public override async Task OnConnectedAsync()

        {

            await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");

            await base.OnConnectedAsync();

        }

        /// 

        /// 客户端断开连接时执行此重写方法

        /// 重写 OnDisconnectedAsync 虚拟方法,以便在客户端断开连接时执行操作。

        /// 如果客户端故意断开连接( connection.stop() 例如,通过调用),则 exception 参数将为 null 。

        /// 但是,如果客户端由于错误(例如网络故障)而断开连接,则 exception 参数将包含描述失败的异常。

        /// 

        /// 

        /// 

        public override async Task OnDisconnectedAsync(Exception exception)

        {

            var user = lstClient.SingleOrDefault(x => x.Id == Context.ConnectionId);

            if (user != null)

            {

                lstClient.Remove(user);

                await Clients.All.GetClientCount(lstClient.Count);

            }

            await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");

            await base.OnDisconnectedAsync(exception);

        }



        #endregion

我自己的完整的HubUtil.cs:

public class HubUtil : Hub

    {

        public static List lstClient = new List();

        /// 

        /// 测试用

        /// 

        /// 

        /// 

        /// 

        public async void SendMessage(string user, string message)

        {

            await Clients.All.ReceiveMessage(user, message);

            return ;

        }

        /// 

        /// 添加连接客户端

        /// 

        /// 

        /// 

        public async void AddClient(MoHubUser user)

        {

            user.Id = Context.ConnectionId;

            user.date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            user.Type = BEAN.ENUM.EnumSYSClass.EnumClientType.Users;

            await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");

            if (!lstClient.Any(b => b.Id == user.Id || b.NickName == user.NickName) )

            {

                //user.NickName = auser.Name;

                lstClient.Add(user);

            }

            await Clients.All.GetClientCount(lstClient.Count);

            await Clients.Users(Context.UserIdentifier).ReceiveMessage("UserConnectionID", Context.ConnectionId);

            return;

        }

        /// 

        /// 获取连接人数

        /// 

        /// 

        public Task GetClientsCount()

        {

            return Clients.Users(Context.UserIdentifier).GetClientCount(lstClient.Count);

        }



        #region SignalR中心 API 提供 OnConnectedAsync 和 OnDisconnectedAsync 虚拟方法来管理和跟踪连接。

        /// 

        /// 处理连接事件

        /// 重写 OnConnectedAsync 虚拟方法,以便在客户端连接到集线器时执行操作,如将其添加到组。

        /// 

        /// 

        public override async Task OnConnectedAsync()

        {

            await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");

            await base.OnConnectedAsync();

        }

        /// 

        /// 客户端断开连接时执行此重写方法

        /// 重写 OnDisconnectedAsync 虚拟方法,以便在客户端断开连接时执行操作。

        /// 如果客户端故意断开连接( connection.stop() 例如,通过调用),则 exception 参数将为 null 。

        /// 但是,如果客户端由于错误(例如网络故障)而断开连接,则 exception 参数将包含描述失败的异常。

        /// 

        /// 

        /// 

        public override async Task OnDisconnectedAsync(Exception exception)

        {

            var user = lstClient.SingleOrDefault(x => x.Id == Context.ConnectionId);

            if (user != null)

            {

                lstClient.Remove(user);

                await Clients.All.GetClientCount(lstClient.Count);

            }

            await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");

            await base.OnDisconnectedAsync(exception);

        }



        #endregion

}

为了更直观一些我写了一个web用来显示客户端连接人数和一些详细的发送消息内容:

 

在wwwroot文件夹里引用添加signalr.js

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第6张图片

然后引用

Js连接SignalR服务端

const connection = new signalR.HubConnectionBuilder()

            .withUrl("@Url.Content("~")/chathub")

            .configureLogging(signalR.LogLevel.Information)

            .build();

 

withUrl 里的就是在Startup.cs 配置路由那里写的一样

再写一个连接方法

async function start() {

            try {

                await connection.start();

                console.log("connected");

                const encodedMsg = `系统 : 连接成功!`;

                const li = document.createElement("li");

                li.textContent = encodedMsg;

                document.getElementById("content").appendChild(li);

                connection.invoke("GetClientsCount");

            } catch (err) {

                console.log(err);

                setTimeout(() => start(), 5000);

            }

        };

//此方法是连接意外关闭时执行的

connection.onclose(async () => {

     await start();

});

//接收来自服务端的消息

        connection.on("ReceiveMessage", (user, message) => {

            const encodedMsg = `${user} : ${message}`;

            const li = document.createElement("li");

            li.textContent = encodedMsg;

            document.getElementById("content").appendChild(li);

        });

        //接收来自服务端的消息

        connection.on("GetClientCount", function (count) {

            document.getElementById('clientCountBox').textContent = '连接人数:' + count;

        })

      

        }

 

红字部分对应写的接口名称和参数

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第7张图片

//发送消息给服务端

        function send() {

            connection.invoke("SendMessage", "服务器", document.getElementById("inputContent").value).catch(err => console.error(err));

红字部分对应HubUitl.cs 类里的方法

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第8张图片

完整html+js:

@*

    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

*@

@{

}





    

    头条新闻控制台输出





    

连接人数:

   
                   
    @**@        

运行:

使用asp,.net core SignalR 实现android java客户端与服务端实时通讯------服务端_第9张图片

成功!

你可能感兴趣的:(SignalR,C#)