技术思绪摘录旅行笔记
Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。

        SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程。实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据。这个也就实现消息的实时推送。我个人理解的实现原理是首先由服务器定制一个函数用于一个客户端调用将消息发送给另一个客户端。当然客户端也需要定抽一个函数。因为服务器需要调用客户端的这个函数。

        

现在说下具体需要包含的文件吧。

     1、SignalR集线器类。用于写一个访求调用客户段的函数。

     2、OWIN类。用于注册服务器的函数。

     3、前台的页面(包括前台的消息框的编写,函数的编写)当然前台需要一些文件。


    一般VS没有自带SignalR类,需要我们在开始任务之前去添加这个功能。选择VS的工具|Nuget包管理器|Nuget包管理器控制台|Install-Package Microsoft.Aspnet.SignalR去安装SignalR。安装完成后,

1、我们在改项目中新建一个文件夹为ChatHubs|新建一个SignalR集线器类,并写上如下代码:

using Microsoft.AspNet.SignalR;

namespace SignalrDemo.ChatHubs
{
    /// <summary>
    /// 集线器
    /// </summary>
    /// <seealso cref="Microsoft.AspNet.SignalR.Hub" />
    public class ChatHub : Hub
    {
        public void SendMessage(string name, string message)
        {
            Clients.All.receiveMessage(name, message);
            //用户调用客户端的函数
        }
    }
}

2、在ChatHubs文件夹下新建一个OWIN类。并写上如下代码:

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(SignalrDemo.ChatHubs.Startup))]
namespace SignalrDemo.ChatHubs
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
            //服务器的hub注册
        }
    }
}

3、在Controllers新建一个Home控制器。并写上如下代码:

using System.Web.Mvc;
using Microsoft.AspNet.SignalR;
using SignalrDemo.ChatHubs;

namespace SignalrDemo.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// 获取通讯类上下文
        /// </summary>
        static readonly IHubContext _myHubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
        
        /// <summary>
        ///通讯类静态化调用
        /// </summary>
        /// <param name="message">The message.</param>
        public static void BroadcastMessage(string message)
        {
            _myHubContext.Clients.All.receiveMessage("服务器", message);
        }       

        /// <summary>
        /// 主动服务器
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
            BroadcastMessage("服务器主动发送的信息");
            return View();
        }

        /// <summary>
        /// 客户端1
        /// </summary>
        /// <returns></returns>
        public ActionResult ClientChat1()
        {
            return View();
        }
        /// <summary>
        /// 客户端2
        /// </summary>
        /// <returns></returns>
        public ActionResult ClientChat2()
        {
            return View();
        }

    }
}

4、在1号2号客户端控制器的方法上右击添加视图(不使用模板,也不使用布局页)后。并写上如下代码:

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>1号客户端</title>
    <meta charset="utf-8" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
    @* BootStarp的引入*@
    <style>
        #message_box {
            height: 400px;
            overflow-y: scroll;
        }
    </style>
    @* 呈现消息 *@
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="jumbotron">
                <ul id="message_box"></ul>
            </div>
            发送者名称:<input id="text_name" class="form-control" value="1号客户端" /><br />
            消息内容:
            <textarea id="text_message" class="form-control" rows="3"></textarea>
            <br />
            <button id="btn_send" class="btn btn-block btn-success">Send</button>
        </div>
    </div>

    <script src="~/Scripts/jquery-3.3.1.js"></script>
    <script src="~/Scripts/jquery.signalR-2.4.0.min.js"></script>
    @* 上述引入的两个文件的顺序不以交换,因为下面这个文件依赖于上面那个文件 *@
    <script src="~/signalr/hubs"></script>
    <!-- 本地没有,动态生成 -->
    <script>
        $(function () {
            var $messageBox = $('#message_box');
            var $textMessage = $('#text_message');
            var $textName = $('#text_name');
            //客户端先与服务器连接起来,拿到服务器的代理操作对象
            var hubConnection = $.connection.chatHub;
            //注册客户端函数
            hubConnection.client.receiveMessage = function (name, message) {
                $messageBox.append('<li><b>' + name + '</b> say:' + message + '</li>')
            }

            //启动连接到服务器
            $.connection.hub.start().done(function () {
                $('#btn_send').bind('click', function () {
                    //调用服务端的函数
                    hubConnection.server.sendMessage($textName.val(), $textMessage.val());
                });
            });
        });
    </script>
</body>
</html>

到此,已经完成了,用两个浏览器分别打开一个两个聊天窗口,输入一个,在另一个浏览器界面就能看到效果了。

然后访问首页,能主动给客户端发信息,也可以单独用其他客户端来发信息,如下控制台代码

using System;
using System.IO;
using System.Net;
using System.Text;

namespace ServiceHub
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Test1());
        }


        public static string Test1()
        {
            PushToWeb("http://localhost:60832/Home/index");
            return "成功";
        }

        /// <summary>
        /// 发出请求并返回数据
        /// </summary>
        /// <param name="url">请求链接</param>
        /// <returns></returns>
        public static string PushToWeb(string url)
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.ContentType = "text/html;charset=UTF-8";
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream myResponseStream = response.GetResponseStream();
                StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
                string retString = myStreamReader.ReadToEnd().Trim('"');
                myStreamReader.Close();
                myResponseStream.Close();
                return retString;
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}


CarsonIT 微信扫码关注公众号 策略、创意、技术

留下您的脚步

 

最近评论

查看更多>>

站点统计

总文章数:275 总分类数:18 总评论数:88 总浏览数:137.64万

精选推荐

阅读排行

友情打赏

请打开您的微信,扫一扫