This screenshot is from a piece I published back in 2002 about improving the web experience by dealing with form data using XMLHTTPObject (a pattern later formally coined AJAX (Asynchronous JavaScript + XML) by Jesse James Garret in 2005). In the early 90’s I wrote a simple TCP socket client for a large supermarket chain to allow remote diagnostics into their POS terminals (remember the Winsock OCX for VB6?). I’ve always been interested in real time communication and this technology is now core to a user experience that we all expect regardless of the medium: desktop web browser, mobile app or even an IoT device — crisp, clear, real time feedback with the software we interact with.
这个截图是从一块我发表 回到 2002年约提高通过处理使用XMLHTTPObject(模式后正式杜撰AJAX(异步JavaScript + XML)形式的数据网络体验杰西詹姆斯加勒特在2005年)。 在90年代初期,我为大型连锁超市编写了一个简单的TCP套接字客户端,以允许对其POS终端进行远程诊断(还记得Winsock OCX for VB6吗?)。 我一直对实时通信很感兴趣,现在,这项技术已成为我们都希望获得的用户体验的核心,无论使用哪种介质:台式机Web浏览器,移动应用程序甚至是IoT设备-随身听都可以提供清晰,清晰,实时的反馈。与我们互动的软件。
Other examples: Dashboards that upgrade graphs/charts in real time, online gaming, and collaboration tools like Teams and Slack. Some more familiar examples include the animated chat bubbles in iMessage when someone else is typing, real time auction countdowns on eBay and real time stock prices on Robinhood.
其他示例:实时升级图形/图表的仪表盘,在线游戏以及Teams和Slack等协作工具。 一些更熟悉的示例包括当有人输入时iMessage中的动画聊天气泡,在eBay上的实时拍卖倒计时以及在Robinhood上的实时股价。
Continuing on this journey of learning, I recently decided to dive into SignalR — a free and open source library for ASP.NET Core that simplifies embedding real-time communications into your apps. SignalR makes it quick and easy to enable your server code and client applications to provide the types of real time UX explained in the examples above. SignalR was created in 2011 by David Fowler and Damian Edwards who now play key roles in the direction and development of ASP.NET. It was released as part of ASP.NET in 2013 — at that time AJAX was the framework of choice for web developers and WebSockets was so new that many browsers didn’t support it. SignalR was designed to harmonize and better manage the myriad of these connection techniques such as polling, long polling and server-sent events. It solves these problems by providing a set of capabilities inside the ASP.NET stack via a set of powerful server- and client-side libraries. With it’s ease of use and comprehensive supporting developer tools (e.g. dedicated tracing tools, etc), ASP.NET developers quickly adopted SignalR and it’s now the de facto stack for real-time ASP.NET development.
在继续学习的过程中,我最近决定深入使用SignalR — Signal.R是ASP.NET Core的免费开放源代码库,可简化将实时通信嵌入到您的应用程序中的过程。 SignalR使您的服务器代码和客户端应用程序能够快速简便地提供上面示例中说明的实时UX类型。 SignalR由David Fowler和Damian Edwards于2011年创建,他们现在在ASP.NET的指导和开发中发挥着关键作用。 它于2013年作为ASP.NET的一部分发布-当时AJAX是Web开发人员的首选框架,而WebSockets太新了,以至于许多浏览器都不支持它。 SignalR旨在协调和更好地管理无数的这些连接技术,例如轮询,长轮询和服务器发送事件。 它通过一组强大的服务器端和客户端库在ASP.NET堆栈内提供了一组功能,从而解决了这些问题。 凭借其易用性和全面的支持开发人员工具(例如专用的跟踪工具等),ASP.NET开发人员Swift采用了SignalR,它现已成为实时ASP.NET开发的实际堆栈。
Of course there are lots of alternative frameworks for real time bi-directional communication such as Firebase, Pusher, RabbitMQ, WebRTC, MQTT and others. I’ll leave it to you to research these and determine which one would ultimately suit your own use case.
当然,还有许多用于实时双向通信的替代框架,例如Firebase,Pusher,RabbitMQ,WebRTC,MQTT等。 我将留给您研究这些内容,并确定哪一个最终适合您自己的用例。
The best way to learn is to build so I decided to leverage one of Microsoft’s sample SignalR applications to teach myself some new skills and see what new ideas might make themselves visible. In additional to my musings into hardware, I’ve also been dabbling in mobile frameworks such as Vue and React Native — so I thought it might be interesting to extend my experimentation with SignalR to a mobile app as well. If you’re interested in learning more about SignalR, Microsoft has fantastic resources to help you and you should definitely check out the Azure SignalR service — as always they provide rich examples and resources to get up and running.
最好的学习方法是进行构建,因此我决定利用Microsoft的示例SignalR应用程序之一来教自己一些新技能,并看看有什么新想法可以使自己变得可见。 除了沉思于硬件之外 ,我还涉猎了Vue和React Native等移动框架-因此,我认为将SignalR的实验也扩展到移动应用程序可能会很有趣。 如果您有兴趣了解有关SignalR的更多信息,Microsoft提供了许多有用的资源来帮助您,并且您一定要查看Azure SignalR服务-因为它们总是提供丰富的示例和资源来启动和运行。
In this walkthrough I’ll show you how to set up a simple chat app as a secure (HTTPS-based) SignalR hub running on ASP.NET Core for Linux. There are tons of chat samples for SignalR around the web but I wanted to pull together an end-to-end ‘story’ that could be a starter project for others to build something bigger. After that I’ll share a simple React Native client I wrote to communicate to the same hub. As a long time .NET fan, I also thought this would be a cool project to explore how ASP.NET Core works on Linux, learn more about Linux in general and of course improve my command line skills :) I learnt a ton during this process so I hope this helps or inspires others who are new/learning to build interesting applications that rely on real-time communications.
在本演练中,我将向您展示如何将一个简单的聊天应用程序设置为在Linux的ASP.NET Core上运行的安全(基于HTTPS)SignalR集线器。 网上有很多SignalR聊天示例,但我想整理一个端到端的“故事”,这可能是其他人构建更大项目的入门项目。 之后,我将共享一个简单的React Native客户端,该客户端是我编写的用于与同一中心通信的。 作为.NET的长期粉丝,我还认为这将是一个很酷的项目,以探索ASP.NET Core在Linux上的工作方式,了解有关Linux的一般知识,当然还可以提高我的命令行技能:)我在此期间学到了很多过程,所以我希望这对新手/学习者有帮助或启发,他们可以构建依赖实时通信的有趣应用程序。
步骤1 —创建一个数字海洋帐户 (Step 1 — Create a Digital Ocean account)
Azure is obviously a great place to host a SignalR chat app (they offer an extremely rich and powerful infrastructure for SignalR on Azure with a ton of samples) but for this exercise I went with DigitalOcean on the recommendation of a colleague. DigitalOcean offers highly configurable virtual servers called ‘droplets’ in 8 data center regions around the world. They offer tons of developer-friendly features wrapped in a simple, powerful portal. It’s also inexpensive — configurations start at $5 per month for a 1GB RAM, 1 vCPU instance with 25GB storage and 1TB traffic/month. Note that everything in this post from Step 3 onwards could easily be done on other cloud platforms like Azure, AWS, etc.
Azure显然是托管SignalR聊天应用程序的好地方(它们为Azure上的SignalR提供了非常丰富和强大的基础结构, 并提供了大量示例 ),但是对于此练习,我在同事的推荐下与DigitalOcean一起使用。 DigitalOcean在全球8个数据中心区域中提供了高度可配置的虚拟服务器,称为“液滴”。 它们通过简单,强大的门户提供了许多开发人员友好的功能。 它也很便宜-1GB RAM,1个具有25GB存储和1TB流量/月的vCPU实例的配置起价为每月5美元。 请注意,本文中从步骤3开始的所有内容都可以轻松在其他云平台(例如Azure,AWS等)上完成。
DigitalOcean actually has a great tutorial on setting up ASP.NET on their platform but I got tripped up quite a bit along the way — so hopefully my tweaks might help others who also might run into similar problems.
DigitalOcean实际上有一个很棒的教程,介绍如何在其平台上设置ASP.NET,但是在此过程中我遇到了很多麻烦-因此希望我的调整可以对也可能遇到类似问题的其他人有所帮助。
Head over to https://www.digitalocean.com and create an account and let’s create a new project. On the left nav bar click ‘+ New Project’
转到https://www.digitalocean.com并创建一个帐户,然后创建一个新项目。 在左侧导航栏上,单击“ +新建项目”
Now let’s create our instance, known as a ‘droplet’. From the top menu, select ‘Create’ then ‘Droplets’:
现在让我们创建一个实例,称为“液滴”。 从顶部菜单中,选择“创建”,然后选择“小滴”:
Let’s configure our droplet. I chose Ubuntu 18.04.3 (LTS) x64 with the Standard/Starter plan at $5/hour — that gives us a 1Gb single CPU instance with 25Gb disk and 1Tb transfer — that’s plenty for now. I’m based in Atlanta so I chose the New York data center and I left all the other options unchecked. I gave my droplet a hostname of ‘ubuntu-medium-signalrdemo’ but you can name it whatever you like.
让我们配置我们的Droplet。 我选择了具有标准/入门版计划的Ubuntu 18.04.3(LTS)x64(每小时5美元),这为我们提供了具有25Gb磁盘和1Tb传输的1Gb单CPU实例-到目前为止,这已经足够了。 我住在亚特兰大,所以我选择了纽约数据中心,而所有其他选项均未选中。 我给我的Droplet命名为“ ubuntu-medium-signalrdemo ”,但是您可以随意命名。
You’ll also be given a couple of options for credentials: password or SSH key. I chose password — if you choose SSH Key just note that we’ll be creating a new user a little later so it might be easier to choose the ‘Password’ option for now.
您还将获得两个凭据选项:密码或SSH密钥。 我选择了密码-如果您选择SSH密钥,请注意,稍后我们将创建一个新用户,因此现在选择“密码”选项可能会更容易。
Click ‘Create Droplet’ at the bottom of the page - this will take a few seconds and we’ll see our new droplet.
点击页面底部的“创建液滴”-这将需要几秒钟,我们将看到新的液滴。
Make a note of our newly assigned IP address — we’ll need it to connect to our instance shortly. With our instance created we have a bunch of configuration to do before we can deploy an app. As I mentioned earlier, one of the goals of this exercise was to host a real domain name and make it secure (HTTPS). I purchased the domain name signalrdemo.com from my preferred registrar and so I’ll be referring to this domain throughout this tutorial so make sure you replace signalrdemo.com with your own domain name throughout the exercise.
记下我们新分配的IP地址-我们将需要它很快连接到我们的实例。 创建实例后,我们需要进行大量配置才能部署应用。 正如我之前提到的,此练习的目标之一是托管一个真实域名并使其安全(HTTPS)。 我从我的首选注册商那里购买了域名signalrdemo.com ,因此在本教程中我将始终引用该域名,因此请确保在整个练习中用您自己的域名替换signalrdemo.com 。
On the left nav bar in our DigitalOcean dashboard, click ‘Networking’:
在DigitalOcean信息中心的左侧导航栏中,点击“网络”:
Enter your domain name and click ‘Add Domain’. We’re taken straight to the domain configuration screen where we can now add our A records. An A Record connects a domain with the public IP address of a website. Let’s add two A records: ‘@’ (which will allow us to hit signalrdemo.com) and ‘www’ (www.signalrdemo.com) both with TTL values of 600. The TTL value determines the duration for which the server will cache these details.
输入您的域名,然后单击“添加域”。 我们直接进入域配置屏幕,现在可以在其中添加A记录。 A记录将域与网站的公共IP地址相连。 让我们添加两个A记录:“ @”(这将使我们能够访问signalrdemo.com )和“ www”( www.signalrdemo.com ),它们的TTL值均为600。TTL值确定服务器缓存的持续时间这些细节。
We now have 5 entries in our DNS records list:
现在,我们的DNS记录列表中有5个条目:
That’s it — the Ubuntu box is ready for configuration. Before start that process we need to configure our domain name at the registrar to point to our droplet.
就是这样-Ubuntu盒子已准备好进行配置。 在开始该过程之前,我们需要在注册服务商处配置我们的域名以指向我们的Droplet。
第2步-将我们的域连接到我们的Droplet (Step 2 — Connect our domain to our droplet)
My registrar of choice is Dotster. There are lots of domain registrars and they all have excellent tutorials on how to configure DNS records so this part will be short. I first added all three DigitalOcean nameservers:
我选择的注册商是Dotster。 域名注册商很多,他们都有关于如何配置DNS记录的出色教程,因此本部分将简短。 我首先添加了所有三个DigitalOcean域名服务器:
I also added three ‘A’ records as follows:
我还添加了三个“ A”记录,如下所示:
That does it for our domain configuration. Now let’s log into our instance and start configuring it.
这就是我们的域配置。 现在,让我们登录到实例并开始配置它。
步骤3 —登录到新的Ubuntu实例 (Step 3 — Log in to your new Ubuntu instance)
To log into our new Linux instance, fire up your terminal of choice (I use Terminal on MacOS and the awesome app Termius on my iPad/iPhone) and log in using our assigned IP address from DigitalOcean. In this example it’s 68.182.98.72 but make sure you use the IP assigned to you:
要登录我们的新Linux实例,请启动您选择的终端(我在MacOS上使用Terminal,在我的iPad / iPhone上使用很棒的应用程序Termius ),然后使用我们从DigitalOcean分配的IP地址登录。 在此示例中为68.182.98.72,但请确保使用分配给您的IP:
# ssh [email protected]
NOTE: The root user is the administrative user in a Linux environment and has very broad privileges. If you plan on doing anything with your instance beyond experimenting here you should create a new, separate user with similar privileges. Being a Linux novice I decided to create a new user. Let’s call this user ‘signalr’.
注: 根用户是Linux环境中的管理用户,并且具有非常广泛的特权。 如果您打算在此处进行实验之外对实例执行任何操作,则应创建一个具有类似特权的新的独立用户。 作为Linux新手,我决定创建一个新用户。 我们将此用户称为“ signalr ”。
# adduser signalr
Enter a password for the new user and select all the defaults.
输入新用户的密码,然后选择所有默认值。
Now let’s give the new user superuser privileges:
现在,给新用户超级用户特权:
# usermod -aG sudo signalr
Logout of root (logout) and now SSH back in with our new signalr user.
注销root( logout ),现在使用新的signalr用户SSH重新登录 。
# ssh [email protected]
Now let’s install Nginx.
现在,让我们安装Nginx。
步骤4 —配置Nginx (Step 4 — Configure Nginx)
Kestrel is the cross-platform web server that ships with for ASP.NET Core. Kestrel is the web server that’s included by default in ASP.NET Core project templates. Kestrel is great for serving dynamic content from an ASP.NET Core application as it provides better request-processing performance and was designed to make ASP.NET as fast as possible. However, Kestrel isn’t considered a full-featured web server because it can’t manage security and serve static files, which is why it is advisable to always run it behind a web server. We’re going to configure Nginx as a reverse proxy for our SignalR application. Nginx is one of Ubuntu’s default repositories so let’s install it using the apt packaging manager. First we tell apt to update itself with all recent packages. The first time you run a command with sudo you’ll be prompted for your password:
Kestrel是ASP.NET Core附带的跨平台Web服务器 。 Kestrel是默认情况下包含在ASP.NET Core项目模板中的Web服务器。 Kestrel非常适合从ASP.NET Core应用程序提供动态内容,因为它提供了更好的请求处理性能,并且旨在使ASP.NET尽可能快。 但是,Kestrel不能被认为是功能齐全的Web服务器,因为它无法管理安全性并无法提供静态文件,因此建议始终在Web服务器后运行它 。 我们将Nginx配置为SignalR应用程序的反向代理。 Nginx是Ubuntu的默认存储库之一,因此让我们使用apt打包管理器进行安装。 首先,我们告诉apt使用所有最新软件包进行自我更新。 第一次使用sudo运行命令时,系统会提示您输入密码:
# sudo apt update
Now install the Nginx package:
现在安装Nginx软件包:
# sudo apt install nginx
After installation is complete, let’s confirm Nginx is installed and running:
安装完成后,让我们确认Nginx已安装并正在运行:
# sudo systemctl status nginx
With the service running, let’s test it out by requesting a page from Nginx. Open up a browser and enter your server’s IP address in your browser’s address bar (you can get your IP address from your DigitalOcean dashboard) — for our example:
服务运行后,让我们从Nginx请求页面进行测试。 打开浏览器,然后在浏览器的地址栏中输入服务器的IP地址(您可以从DigitalOcean仪表板获取IP地址),例如:
http://68.183.98.72 <-- change this to your own IP address
You should see the default Nginx landing page:
您应该看到默认的Nginx登陆页面:
Our A records should have propagated by now so you should also be able to hit http://www.signalrdemo.com (try it with your own domain name).
我们的A记录应该已经传播了,因此您也应该可以访问http://www.signalrdemo.com (使用您自己的域名尝试)。
If you’re not seeing this screen, go back and check your settings at your domain registrar and also the domain settings back in DigitalOcean. To learn more about how to manage your Nginx instance, visit the documentation at https://docs.nginx.com/nginx/admin-guide/ — there are also plenty of guides online.
如果没有看到此屏幕,请返回并在域注册商处检查设置,然后再在DigitalOcean中检查域设置。 要了解有关如何管理Nginx实例的更多信息,请访问https://docs.nginx.com/nginx/admin-guide/上的文档-在线上也有很多指南。
步骤5 —安装.NET Core 3.1 (Step 5 — Install .NET Core 3.1)
Let’s kill the Nginx process for now by pressing CTRL-C. We’ll restart it later. Now that we know Nginx is working let’s use it to reverse proxy the built in ASP.NET Core web server we mentioned earlier — to do that we’ll need to install the .NET Core SDK (and runtime). If you’re interested in exploring this further there’s a super detailed tutorial on how to do that for Ubuntu over at Microsoft.
现在,通过按CTRL-C杀死Nginx进程。 我们稍后会重新启动。 现在我们知道Nginx正在工作,让我们使用它来反向代理我们前面提到的内置ASP.NET Core Web服务器-为此,我们需要安装.NET Core SDK(和运行时)。 如果您有兴趣进一步探索它,可以在Microsoft上找到有关如何为Ubuntu执行此操作的超级详细教程 。
Let’s start by downloading the Microsoft .NET Core package for Ubuntu 18.04:
首先下载用于Ubuntu 18.04的Microsoft .NET Core软件包:
# wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
Use dpkg with the -i flag to add the Microsoft package signing key to our list of trusted keys and add the package repository, then install it.
使用带有-i标志的dpkg将Microsoft软件包签名密钥添加到我们的受信任密钥列表中,并添加软件包存储库,然后安装它。
# sudo dpkg -i packages-microsoft-prod.deb
There are a couple of other packages we need to install:
我们还需要安装其他几个软件包:
# sudo add-apt-repository universe
# sudo apt install apt-transport-https
universe is a repository of community-maintained free and open-source software. apt-transport allows the use of repositories accessed via HTTPS. Now let’s make sure all our repositories are up to date with their newest versions and associated dependencies:
Universe是社区维护的免费和开源软件的存储库。 apt-transport允许使用通过HTTPS访问的存储库。 现在,让我们确保所有存储库都是最新的,并具有其最新版本和相关的依赖关系:
# sudo apt update
Now let’s install the .NET runtime. I’m opting for the latest version which is currently 3.1:
现在,让我们安装.NET运行时。 我选择了当前版本为3.1的最新版本:
sudo apt install dotnet-sdk-3.1
We’re done installing .NET Core so let’s do some cleanup:
我们已经完成了.NET Core的安装,因此让我们进行一些清理:
# rm packages-microsoft-prod.deb
步骤6 —配置Nginx (Step 6 — Configure Nginx)
I mentioned earlier that Nginx is going to reverse proxy our Kestrel instance so let’s set that up now. Create the directory for
我之前提到Nginx将反向代理我们的Kestrel实例,所以现在就进行设置。 使用-p标志为
# sudo mkdir -p /var/www/signalrdemo.com
Next, assign ownership of the directory with the $USER environment variable and make sure the newly created folder that will house our web app has the right permissions:
接下来,使用$ USER环境变量分配目录的所有权,并确保用于容纳我们的Web应用程序的新创建的文件夹具有正确的权限:
# sudo chown -R $USER:$USER /var/www/signalrdemo.com
# sudo chmod -R 755 /var/www/signalrdemo.com
Now let’s create a sample index.html page using vi, nano or your favorite text editor:
现在,我们使用vi , nano创建一个示例index.html页面 或您最喜欢的文本编辑器:
# vi /var/www/signalrdemo.com/index.html
Inside, add the following sample HTML. If you’re new to vi, press i to start typing:
在内部,添加以下示例HTML。 如果您不熟悉vi ,请按i开始输入:
Welcome to signalrdemo.com
(Once again if you’re new to vi, save this snippet by pressing ESC then :wq to write/save the file). Before we can serve up this .html file, we need to create an Nginx server block. Just like virtual hosts in Apache or IIS, a server block encapsulates configuration details about how to host a domain. Nginx on Ubuntu 18.04 installs with one server block enabled by default that is configured to serve documents out of /var/www/html. We’re going to serve content out of the folder we just created by creating a new server block.
(如果您不熟悉vi ,请再次按ESC,然后按:wq保存/保存文件)。 在提供此.html文件之前,我们需要创建一个Nginx 服务器块 。 就像Apache或IIS中的虚拟主机一样,服务器块封装了有关如何托管域的配置详细信息。 Ubuntu 18.04上的Nginx安装时默认启用了一个服务器块,该服务器块配置为提供/ var / www / html之外的文档。 我们将通过创建新的服务器块,将内容从刚刚创建的文件夹中提供。
# sudo vi /etc/nginx/sites-available/signalrdemo.com
Paste in the following configuration block and remember to replace signalrdemo.com with your own domain name. You can learn more about server blocks at the Nginx documentation repo or over at DigitalOcean here):
粘贴以下配置块,并记住用您自己的域名替换signalrdemo.com 。 您可以在Nginx文档仓库中或在DigitalOcean的此处 了解有关服务器块的更多信息 :
Save this file. NOTE: You’ll notice the value for the proxy header ‘Connection’ is set to $http_connection instead of keep-alive. Special thanks to @raen over at Stack Overflow — my SignalR hub was erroring out with a ‘Not Found’ error and replacing keep-alive with $http_connection fixed the problem.
保存此文件。 注意:您会注意到代理标头'Connection'的值设置为$ http_connection而不是keep-alive 。 特别感谢Stack Overflow上的 @raen —我的SignalR集线器因出现“未找到”错误而出错,并用$ http_connection替换了keep-alive 来解决此问题。
Now we need to enable the block by creating a symbolic link from it to the sites-enabled directory which Nginx reads from during startup:
现在,我们需要通过创建一个链接到Nginx在启动过程中从中读取站点的目录创建符号链接来启用该块:
# sudo ln -s /etc/nginx/sites-available/signalrdemo.com /etc/nginx/sites-enabled/
Our server block is now enabled and configured to respond to requests based on the listen and server_name directives inside the server block (you can read more about how Nginx processes these directives here). So now signalrdemo.com will respond to requests for signalrdemo.com and www.signalrdemo.com . Let’s restart Nginx to apply these changes:
现在,我们的服务器块已启用并配置为基于服务器块内的listen和server_name指令响应请求(您可以在此处阅读有关Nginx如何处理这些指令的更多信息)。 因此, signalrdemo.com现在将响应对signalrdemo.com和www.signalrdemo.com的请求。 让我们重新启动Nginx以应用这些更改:
# sudo service nginx restart
..and now visit www.signalrdemo.com in our browser:
..,然后在我们的浏览器中访问www.signalrdemo.com :
We now have our domain directed to DigitalOcean and it’s serving up content.
现在,我们将域名定向到DigitalOcean并提供内容。
Now would be a good time to think about security so let’s configure Nginx to serve up content over HTTPS.
现在是考虑安全性的好时机,因此让我们将Nginx配置为通过HTTPS提供内容。
第7步-安装Certbot (Step 7 — Installing Certbot)
To serve content securely via HTTPS, we need to obtain an SSL certificate for our domain from a registered certificate authority (CA). There are lots of CAs offering paid SSL certificates such as Comodo and Symantec but a new open-source provider called Let’s Encrypt has become popular because it provides an easy way to obtain and install TLS/SSL certificates — and they’re also free! It simplifies the process by providing a utility for Linux called Certbot that attempts to automate nearly all of the required steps. Certbot will fully automate the entire process of obtaining and installing a certificate.
为了通过HTTPS安全地提供内容,我们需要从注册的证书颁发机构(CA)获得用于我们域的SSL证书。 有许多提供付费SSL证书的CA,例如Comodo和Symantec,但是一种名为Let's Encrypt的新开源提供商已变得流行,因为它提供了一种获取和安装TLS / SSL证书的简便方法-并且它们也是免费的! 通过为Linux提供称为Certbot的实用程序来简化几乎所有必需的步骤,从而简化了该过程。 Certbot将完全自动化获取和安装证书的整个过程。
Let’s make sure we are using the most up to date version of Certbot by installing the latest repository:
通过安装最新的存储库,确保我们使用的是最新版本的Certbot:
# sudo add-apt-repository ppa:certbot/certbot
Now install Certbot’s Nginx package:
现在安装Certbot的Nginx软件包:
# sudo apt install python-certbot-nginx
Certbot provides a variety of ways to obtain SSL certificates through plugins — the Nginx plugin will take care of reconfiguring Nginx and reloading the config whenever necessary:
Certbot提供了多种通过插件获取SSL证书的方法-Nginx插件将负责重新配置Nginx并在必要时重新加载配置:
sudo certbot --nginx -d signalrdemo.com -d www.signalrdemo.com
Since this is the first time running Certbot it will be prompt for an email address and ask to agree to the terms of service. After doing so, Certbot will communicate with the Let’s Encrypt server, then run a challenge to verify that we control the domain we’re requesting a certificate for — because signalrdemo.com is now live, we know this challenge will succeed. During the installation process, Certbot will ask how to handle redirects from HTTP automatically to HTTPS — I chose option 2. Here’s what the process should look like:
由于这是第一次运行Certbot,因此会提示您输入电子邮件地址,并要求同意服务条款。 完成此操作后,Certbot将与Let's Encrypt服务器通信,然后进行质询以验证我们是否控制了我们要为其申请证书的域—因为signalrdemo.com现在处于活动状态,我们知道此挑战将成功。 在安装过程中,Certbot会询问如何自动处理从HTTP到HTTPS的重定向-我选择了选项2。过程如下所示:
Certbot-auto will automatically generate the SSL certificate and key and store/install them in the directory /etc/letsencrypt. Certbot will also modify our server block (/etc/nginx/sites-enabled/signalrdemo.com) with some additional entries and has now basically HTTPS enabled our site:
Certbot-auto将自动生成SSL证书和密钥,并将其存储/安装在目录/ etc / letsencrypt中 。 Certbot还将使用一些其他条目来修改我们的服务器块( /etc/nginx/sites-enabled/signalrdemo.com ),现在基本上已经通过HTTPS启用了我们的站点:
NOTE: You may see an extra server block added to the end of the current one — if you see that, please remove the entire extra block and save the server block file. Let’s quickly test to make sure that there are no syntax errors in any of your Nginx files:
注意:您可能会看到一个额外的服务器块添加到当前服务器块的末尾—如果看到,请删除整个额外的块并保存服务器块文件。 让我们快速进行测试,以确保任何Nginx文件中都没有语法错误:
# sudo nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Finally we need to restart Nginx to enable these changes:
最后,我们需要重新启动Nginx以启用这些更改:
# sudo systemctl restart nginx
Let’s confirm by reloading your website or just change the prefix from http to https to visit https://www.signalrdemo.com — notice your browser’s security indicator. It should indicate that the site is properly secured, usually with a green lock icon. Bingo — our site is serving content over HTTPS:
让我们通过重新加载您的网站进行确认,或者仅将前缀从http更改为https即可访问https://www.signalrdemo.com —注意浏览器的安全指示器。 它应指示站点已正确保护,通常带有绿色的锁定图标。 Bingo-我们的网站正在通过HTTPS提供内容:
NOTE: If you’re interesting learning more about how to increase security for a site with Nginx and Let’s Encrypt, check out this blog which will show you how to further strengthen the security and reliability of your site.
注意:如果您有兴趣学习更多有关如何使用Nginx和Let's Encrypt增强站点安全性的信息,请查看此博客, 该博客将向您展示如何进一步增强站点的安全性和可靠性。
第8步-创建并部署我们的第一个ASP.NET应用 (Step 8— Create and deploy our first ASP.NET app)
Everything is ready for us to start serving up a secure ASP.NET web app so let’s create that now. Let’s create a folder where we’ll host the app and use the dotnet CLI to create scaffolding to a simple web app.
我们已经准备就绪,可以开始提供安全的ASP.NET Web应用程序了,现在就创建它。 让我们创建一个文件夹,在其中托管应用程序,并使用dotnet CLI为简单的Web应用程序创建脚手架。
# cd /var/www/signalrdemo.com
# dotnet new webapp
This will create a default ASP.NET web application and supporting files:
这将创建一个默认的ASP.NET Web应用程序和支持文件:
At this point I had to make a small tweak — the default setting for the WebApp we created includes a directive about redirection inside Startup.cs and this was tripped me up so I commented it out — so vi Startup.cs and comment this line out (line 43):
在这一点上,我必须进行一些微调-我们创建的WebApp的默认设置包括Startup.cs中有关重定向的指令,这使我不胜其烦 ,所以我将其注释掉了-因此vi Startup.cs并注释掉这行(第43行):
// app.UseHttpsRedirection();
Let’s save our changes and now we can build the app.
让我们保存更改,现在可以构建应用程序了。
# dotnet build
Now publish the app:
现在发布该应用程序:
# dotnet publish
Our web app is ready to run. Now when it does, it will be running on localhost:5000 and localhost:5001 — so how do we see it from the outside world? We need make a small tweak to our server block to proxy port 80 to the ASP.NET application running on port 5000 (and vice verse for 443 which will redirect to 5001). Add the following line to the beginning of the ‘location’ section of the server block at /etc/nginx/sites-enabled/signalrdemo.com:
我们的网络应用已准备就绪,可以运行。 现在,当它运行时,它将在localhost:5000和localhost:5001上运行 -那么我们如何从外界看到它呢? 我们需要对服务器块进行一些小的调整,以将端口80代理到在端口5000上运行的ASP.NET应用程序(对于443,反之则将重定向到5001)。 将以下行添加到/etc/nginx/sites-enabled/signalrdemo.com上服务器块的“位置”部分的开头:
proxy_pass http://localhost:5000;
The full server block now reads:
完整的服务器块现在显示为:
Save this change and restart Nginx:
保存此更改并重新启动Nginx:
# sudo systemctl restart nginx
Now we can start the app:
现在我们可以启动该应用程序:
# dotnet bin/Debug/netcoreapp3.1/signalrdemo.com.dll
The CLI shows our app is running. Head back to your browser and refresh/visit https://www.signalrdemo.com:
CLI显示我们的应用程序正在运行。 返回浏览器并刷新/访问https://www.signalrdemo.com :
We can now serve ASP.NET apps over HTTP/HTTPS on DigitalOcean so let’s stand up the chat app.
现在,我们可以在DigitalOcean上通过HTTP / HTTPS提供ASP.NET应用程序,因此让我们站起来聊天应用程序。
第9步-创建我们的服务器端SignalR应用 (Step 9 — Create our server side SignalR app)
Head over to the Microsoft SignalR site and check out their sample chat application:
转到Microsoft SignalR网站,并查看其示例聊天应用程序 :
I’ve based my sample chat app on this exact code from Microsoft but with a few important tweaks. The demo code appears to have been designed to run on a local development machine so many thanks to ASP.NET Core guru Ibrahim Šuta for helping me figure out a couple of key hurdles to resolving this. (If you need some deep-trench ASP.NET/Core work/consulting I strongly recommend you reach out to Ibrahim directly).
我已经基于Microsoft的确切代码创建了示例聊天应用程序,但是进行了一些重要的调整。 由于ASP.NET Core专家IbrahimŠuta帮助我找出解决该问题的两个关键障碍,因此该演示代码似乎旨在在本地开发计算机上运行。 (如果您需要一些深入的ASP.NET/核心工作/咨询服务,我强烈建议您直接与易卜拉欣联系)。
So we have here two versions of this app — one to host on signalrdemo.com (SignalRWebServer https://github.com/jonathanzufi/SignalRWebServer) and one to run locally for testing/verification (SignalRWebClient https://github.com/jonathanzufi/SignalRWebClient). They’re split into two projects even though they are 99% similar for reasons I’ll explain in a moment.
因此,我们在这里有此应用程序的两个版本-一个版本可托管在signalrdemo.com (SignalRWebServer https://github.com/jonathanzufi/SignalRWebServer )上,另一个版本可在本地运行以进行测试/验证(SignalRWebClient https://github.com/ jonathanzufi / SignalRWebClient )。 尽管它们有99%的相似性,但由于我稍后会说明的原因,它们被分为两个项目。
Let’s start with the server app: the code provided by Microsoft works great on your local development machine, but as soon as we host it on a public IP in order to communicate over the open web, there are security related considerations that we need to address in order to allow traffic to hit our SignalR hub. Browser security prevents a web page from making requests to a different domain than the one that served the web page. This restriction is called the same-origin policy. The same-origin policy prevents a malicious site from reading sensitive data from another site. In our case we want to allow our chat client to make cross-origin requests to our app. To do this, we need to enable CORS (Cross Origin Resource Sharing) middleware to allow this to happen. To read up more about this, check out Microsoft’s detailed blog.
让我们从服务器应用程序开始:Microsoft提供的代码在您的本地开发机器上运行良好,但是一旦我们将其托管在公共IP上以便通过开放式网络进行通信,就需要解决与安全性相关的注意事项为了让流量到达我们的SignalR集线器。 浏览器安全性阻止了网页向与服务该网页的域不同的域发出请求。 此限制称为同源策略 。 同源策略可防止恶意站点从另一个站点读取敏感数据。 在我们的情况下,我们希望允许聊天客户端向我们的应用发出跨域请求。 为此,我们需要启用CORS(跨源资源共享)中间件以使这种情况发生。 要阅读有关此内容的更多信息,请查看Microsoft的详细博客 。
So back in our server app in Startup.cs we set our CORS policy name:
然后回到Startup.cs中的服务器应用程序 我们设置了CORS政策名称:
private string CorsPolicyName = “MyCorsPolicy”;
Further down inside ConfigureServices we define the CORS policy:
在ConfigureServices内部,我们定义了CORS策略:
services.AddCors(options => options.AddPolicy(CorsPolicyName, builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins(
“https://localhost:5001”,
“https://localhost:44390”,
“http://localhost:5000”);
}));
This code will allows a SignalR browser client running on our local machine in dev (i.e. inside Visual Studio) to access our SignalR app hosted on https://www.signalrdemo.com. This is important if we decide to tinker with the client Visual Studio project connected to our live hub.
此代码将允许在开发人员的本地计算机(即Visual Studio内部)中运行的SignalR浏览器客户端访问https://www.signalrdemo.com上托管的SignalR应用程序。 如果我们决定修改连接到实时中心的客户端Visual Studio项目,则这一点很重要。
Finally for our server app, remember that we’re using Nginx to reverse proxy calls from the outside to the .NET Kestrel engine. For this reason we need some additional glue code to handle the forwarding of these requests. From the Microsoft docs:
最后,对于我们的服务器应用程序,请记住我们正在使用Nginx将来自外部的代理调用反向到.NET Kestrel引擎。 因此,我们需要一些附加的粘合代码来处理这些请求的转发。 从Microsoft文档:
Because requests are forwarded by reverse proxy, use the Forwarded Headers Middleware from the Microsoft.AspNetCore.HttpOverrides package. The middleware updates the
Request.Scheme
, using theX-Forwarded-Proto
header, so that redirect URIs and other security policies work correctly.因为请求是通过反向代理转发的,所以请使用Microsoft.AspNetCore.HttpOverrides包中的转发的头中间件 。 中间件使用
X-Forwarded-Proto
标头更新Request.Scheme
,以便重定向URI和其他安全策略正常工作。Any component that depends on the scheme, such as authentication, link generation, redirects, and geolocation, must be placed after invoking the Forwarded Headers Middleware. As a general rule, Forwarded Headers Middleware should run before other middleware except diagnostics and error handling middleware. This ordering ensures that the middleware relying on forwarded headers information can consume the header values for processing.
依赖于方案的任何组件,例如身份验证,链接生成,重定向和地理位置,都必须在调用转发的头中间件之后放置。 作为一般规则,除了诊断和错误处理中间件外,转发标头中间件应先于其他中间件运行。 此排序确保依赖于转发的标头信息的中间件可以使用标头值进行处理。
Invoke the UseForwardedHeaders method at the top of
Startup.Configure
before calling other middleware. Configure the middleware to forward theX-Forwarded-For
andX-Forwarded-Proto
headers:在调用其他中间件之前,请调用
Startup.Configure
顶部的UseForwardedHeaders方法。 配置中间件以转发X-Forwarded-For
和X-Forwarded-Proto
标头:
So that’s exactly what we do inside Startup.cs:
这就是我们在Startup.cs中执行的操作:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
(Also note we define the Microsoft.AspNetCore.HttpOverrides framework at the top of the Startup.cs).
(还要注意,我们在Startup.cs的顶部定义了Microsoft.AspNetCore.HttpOverrides框架)。
So this explains the tweaks required to get that sample working on the open web. Back in our terminal, press CTRL-C to stop .NET. Now let’s install this server chat hub app on to our server by cloning the repo, build, publish and the run the app:
因此,这说明了使该示例在开放的Web上运行所需的调整。 回到我们的终端,按CTRL-C停止.NET。 现在,通过克隆存储库,构建,发布和运行该应用程序,将该服务器聊天中心应用程序安装到我们的服务器上:
# cd /var/www/signalrdemo.com
# git clone https://github.com/jonathanzufi/SignalRWebServer .
# dotnet build
# dotnet publish
# cd SignalRWebServer
# dotnet bin/Debug/netcoreapp3.1/SignalRWebServer.dll
The chat app should now be running — bring up two browser windows side by side pointing to our domain and we can see the chat app in action:
聊天应用现在应该正在运行-并排打开两个浏览器窗口,指向我们的域,我们可以看到聊天应用正在运行:
Now to the SignalRWebClient project —I spun this project out as a separate app so that we can load it into Visual Studio to learn more about how it works and still communicate with the openly hosted hub at signalrdemo.com. This project only has a single change from the Microsoft demo code — it’s minor but obvious — we need to change the endpoint to the fully qualified domain name of where the server is hosted. So we change the endpoint in wwwroot\js\chat.js to:
现在进入SignalRWebClient项目-我将该项目作为一个单独的应用程序拆分出来,以便我们可以将其加载到Visual Studio中,以了解有关其工作方式的更多信息,并仍然与signalrdemo.com上的开放托管中心进行通信 。 这个项目与Microsoft演示代码只有一个更改-很小但是很明显-我们需要将端点更改为托管服务器的标准域名。 因此,我们将wwwroot \ js \ chat.js中的端点更改为:
var connection = new signalR.HubConnectionBuilder().withUrl(“https://signalrdemo.com/chatHub").build();
‘/chatHub’ is the name of the route we defined in the server app so this gets added to our fully qualified domain name as the endpoint for any client applications that want to communicate with the SignalR hub. Make sure you change this to your own domain name. Pull the code down for the SignalRWebClient project from GitHub on to your local Visual Studio environment and run it and you’ll be able to successfully talk to the live hub.
“ / chatHub”是我们在服务器应用程序中定义的路由的名称,因此会将其添加到我们的标准域名中,作为要与SignalR集线器通信的所有客户端应用程序的端点。 确保将其更改为您自己的域名。 将SignalRWebClient项目的代码从GitHub下拉到本地Visual Studio环境并运行它,您将能够成功与实时中心进行对话。
We’re nearly done. The last step is to configure Nginx to automatically run our server app in the background without having to leave a terminal window open. Let’s create a new service file:
我们快完成了。 最后一步是将Nginx配置为在后台自动运行我们的服务器应用程序,而无需打开终端窗口。 让我们创建一个新的服务文件:
# sudo vi /etc/systemd/system/signalrdemo.service
Add the following content and remember to plug in your own domain name:
添加以下内容,并记住插入您自己的域名:
Nginx service definition file for our server app 我们的服务器应用程序的Nginx服务定义文件This service configuration file specifies the location of the project’s folder with WorkingDirectory and the command to execute at the start of the process in ExecStart. This also specifies using the RestartSec directive to restart the systemd service if the .NET runtime service crashes. Save this file and let’s enable the new service created:
该服务配置文件使用WorkingDirectory指定项目文件夹的位置,并在ExecStart中的过程开始时指定要执行的命令。 这还指定如果.NET运行时服务崩溃,则使用RestartSec指令重新启动systemd服务。 保存此文件,然后启用创建的新服务:
# sudo systemctl enable signalrdemo.service
Now start the service:
现在启动服务:
# sudo systemctl start signalrdemo.service
Finally let’s check it’s status:
最后,让我们检查一下它的状态:
# sudo systemctl status signalrdemo.service
This means our .NET server app is running in the background so we can close the terminal session. We are pretty much done — we can now hit our server app from anywhere:
这意味着我们的.NET服务器应用程序在后台运行,因此我们可以关闭终端会话。 我们已经完成了很多工作,现在我们可以从任何地方访问我们的服务器应用程序:
IMPORTANT: Don’t forget about your running service! Make sure you stop the running service with sudo systemctl stop signalrdemo.service when/if you’re done so you don’t incur any unwanted charges. You can also easily destroy the droplet as well.
重要提示:不要忘记您的运行服务! 确保/如果完成,请使用sudo systemctl stop signalrdemo.service停止正在运行的服务,以免产生任何不必要的费用。 您还可以轻松地破坏液滴。
第10步-创建我们的React Native应用 (Step 10— Create our React Native app)
When SignalR was originally released, almost every Web application used jQuery, so it was an easy decision for the SignalR JavaScript client to depend on jQuery as well. Today a lot of jQuery’s functionality can be achieved with plain JavaScript allowing a frictionless developer experience integrating into mature frameworks such as Angular, React/React Native, and Vue. I’ve recently taken an interest with React Native so I chose that framework for this example. WebSockets are also now available in all major browsers and are now the standard for real-time Web communications and the SignalR Javascript client is available via npm and Content Delivery Networks (CDNs) which makes it easy to ingest into React Native (or other mobile frameworks).
当SignalR最初发布时,几乎每个Web应用程序都使用jQuery,因此SignalR JavaScript客户端也依赖jQuery是一个容易的决定。 如今,使用普通JavaScript可以实现许多jQuery的功能,从而使开发人员能够毫不费力地将体验集成到Angular,React / React Native和Vue等成熟的框架中。 我最近对React Native产生了兴趣,因此在此示例中选择了该框架。 WebSockets现在也可以在所有主要的浏览器中使用,并且现在是实时Web通信的标准,并且SignalR Javascript客户端可以通过npm和Content Delivery Networks(CDN)获得,这使得可以轻松地将其引入React Native(或其他移动框架) )。
Let’s examine a simple, single page React Native client to talk to our SignalR hub — take a look at https://github.com/jonathanzufi/SignalR-react-native-client.
让我们研究一个简单的单页面React Native客户端,以与我们的SignalR集线器进行对话-看看https://github.com/jonathanzufi/SignalR-react-native-client 。
I built this against iOS as my screenshots reflect, but this should run just fine on Android as well although I have not tested it (if you hit a problem please let me know).
我根据屏幕快照反映的情况在iOS上构建了此文件,但尽管我尚未对其进行测试,但它在Android上也应该可以正常运行(如果遇到问题,请告诉我)。
Here are the instructions for building this code with the React Native CLI — if you prefer Expo, use expo init with the Expo CLI to make a new project, and then copy over all the JavaScript source code from this project, and then repeat the same below to install npm/Cocoapod dependencies. I was a fan of Expo for a while but I’ve come to prefer the iOS simulator as I feel like it will be a shorter path to publishing something to the App Store.
以下是使用React Native CLI构建此代码的说明-如果您更喜欢Expo,则将expo init与Expo CLI一起使用以创建一个新项目,然后复制该项目中的所有JavaScript源代码,然后重复相同的步骤下面安装npm / Cocoapod依赖项。 我曾经是Expo的粉丝,但是我开始偏爱iOS模拟器,因为我觉得这将是向App Store发布内容的捷径。
Let’s pull down the repo, install the npm/Cocoapod dependencies and run it in the iOS simulator (this assumes you have the React Native CLI installed along with XCode):
让我们拉下存储库,安装npm / Cocoapod依赖项,然后在iOS模拟器中运行它(假设您已经安装了React Native CLI和XCode):
# git clone https://github.com/jonathanzufi/SignalR-ReactNativeClient
# cd SignalR-ReactNativeClient
# yarn install
# cd ios && pod install
# cd ..
# npx react-native run-ios
Some areas of interest:
一些感兴趣的领域:
const errorHandler = (e, isFatal) => {
console.log(‘Global error handler’);
}
setJSExceptionHandler(errorHandler, true);
It took me some time to learn about the lifecycle of a connection event in SignalR and along the way I saw some runtime errors that were hard to catch so I used the react-native-exception-handler package as a catch-all to help narrow things down. This isn’t very elegant but it helped me continue developer and I’m looking forward to learning more about debugging tools in React Native.
我花了一些时间来了解SignalR中连接事件的生命周期,并且一路上我看到了一些难以捕获的运行时错误,因此我使用react-native-exception-handler包作为包罗万象,以帮助缩小事情下来。 这不是很优雅,但是它帮助我继续了开发人员,而且我期待了解有关React Native中调试工具的更多信息。
const hub_endpoint = ‘https://signalrdemo.com/chatHub';
Here we’re hardcoding the hub endpoint. It would be nice to harden the example to work with any endpoint but make sure you change this to your own URL.
在这里,我们对集线器端点进行硬编码。 最好使该示例与任何端点一起使用,但是要确保将其更改为自己的URL,这将是很好的。
I use a useEffect React hook to initialize a SignalR connection object and then create/start a connection — during this initialization (of a HubConnectionBuilder object) I initialize it with a logging level of LogLevel.Debug which was really helpful in terms of understanding what SignalR does in the background.
我使用useEffect React钩子来初始化SignalR连接对象,然后创建/启动连接-在该初始化过程中(对HubConnectionBuilder对象的初始化),我使用LogLevel.Debug的日志记录级别对其进行初始化,这对于理解什么SignalR确实很有帮助在后台执行。
I also set up some event handlers for disconnects, reconnects and what to do with incoming messages. I use a state array called messageLog to house all incoming messages and a FlatList to render them with a simple MessageItem functional component to render each item of the message log as new messages are sent and received (I love the simplicity and power of the the FlatList component). For incoming messages we use the on method of the HubConnection object:
我还为断开连接,重新连接以及如何处理传入消息设置了一些事件处理程序。 我使用一个名为messageLog的状态数组来容纳所有传入消息,并使用FlatList来使用一个简单的MessageItem功能组件来呈现它们,以在发送和接收新消息时呈现消息日志中的每个项目(我喜欢FlatList的简单性和强大功能零件)。 对于传入的消息,我们使用HubConnection对象的on方法:
connection.on("ReceiveMessage", function (user, message) {
setMessageLog(messageLog => [...messageLog.concat({
id: Date.now().toString(),
user: user,
message: message
})]);
});
This is an important concept to understand with SignalR — back on the server, hubs are created by declaring a class that inherits from Hub, and then we add public methods to it. Clients (i.e. our mobile app) can call those methods that are defined as public.
这是用SignalR理解的重要概念-回到服务器上,通过声明继承自Hub的类来创建集线器 ,然后向其中添加公共方法。 客户(即我们的移动应用程序)可以调用那些定义为public的方法 。
We specify a return type and parameters, including complex types and arrays, as you would in any C# method, and SignalR handles the serialization and deserialization of complex objects and arrays in your parameters and return values (our parameters user and message are very simple). So in our case, we defined the method name ReceiveMessage which is why we use it when we initialize the connection inside the mobile app.
我们指定返回类型和参数,包括复杂类型和数组,就像在任何C#方法中一样,SignalR处理参数和返回值中复杂对象和数组的序列化和反序列化(我们的参数user和message非常简单) 。 因此,在本例中,我们定义了方法名称ReceiveMessage ,这就是为什么在移动应用程序内部初始化连接时使用它的原因。
The app tries to gracefully handle server side disconnects — you can see below when I stop the ASP.NET service, the app reflects a disconnected state and allows manual reconnection. My code is primitive — see here for a deep dive discussion about connection events and how SignalR works under the covers when a connection is interrupted or broken. One simple tweak is to add the .withAutomaticReconnect() method when initializing HubConnectionBuilder but I’ll leave this to you as an exercise.
该应用程序尝试正常处理服务器端断开连接-当我停止ASP.NET服务时,您可以在下面看到,该应用程序反映了断开连接状态并允许手动重新连接。 我的代码很原始- 请参见此处 ,深入探讨连接事件以及当连接中断或断开时SignalR在幕后的工作方式。 一个简单的调整是在初始化HubConnectionBuilder时添加.withAutomaticReconnect()方法,但我将在练习中留给您。
That wraps it all up! Stepping back, we’ve effectively created simple scaffolding for what could be extended for any kind of real time communications use case — hopefully this will accelerate any ideas you might have!
结束了! 退一步,我们已经有效地创建了简单的支架,可以扩展到任何类型的实时通信用例中,希望可以加速您可能拥有的任何想法!
If you’ve made it this far — thank you! Documenting this walkthrough really cemented many of the concepts in this post for me personally and I hope they do the same for you, or at least inspire you to build something cool. If you have any comments or suggestions please post them below or contact me directly — I’d love to know what I could have done better.
如果您到目前为止已经做到了-谢谢! 记录此演练确实为我个人巩固了本文中的许多概念,我希望它们为您做同样的事情,或者至少激发您构建一些很棒的东西。 如果您有任何意见或建议,请在下面发布或直接与我联系-我很想知道我可以做得更好。
A special shout out to Ibrahim Šut, Rodhan Hickey, Nimesh Neema and Stefan Georg for their guidance and advice.
特别向易卜拉欣·索特(IbrahimŠut), 罗丹 ·希基( Rodhan Hickey) , 尼梅什 ·内玛( Nimesh Neema)和斯特凡·乔治 ( Stefan Georg)表示感谢。
Keep coding.
继续编码。
翻译自: https://medium.com/swlh/learn-how-to-deploy-a-react-native-chat-client-against-a-signalr-hub-on-asp-net-core-for-linux-1b73af1cb2be