假设以下代码在Windows服务上运行。我必须将数据从计算机上的Windows服务发送到在同一台计算机上打开的网页(但未托管在该计算机上)。
static void Main(string[] args)
{
Int32 counter = 0;
while (counter < 100)
{
SendUDP("127.0.0.1", 49320, counter.ToString(), counter.ToString().Length);
Thread.Sleep(2000);
counter++;
}
}
public static void SendUDP(string hostNameOrAddress, int destinationPort, string data, int count)
{
IPAddress destination = Dns.GetHostAddresses(hostNameOrAddress)[0];
IPEndPoint endPoint = new IPEndPoint(destination, destinationPort);
byte[] buffer = Encoding.ASCII.GetBytes(data);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
for (int i = 0; i < count; i++)
{
socket.SendTo(buffer, endPoint);
}
socket.Close();
System.Console.WriteLine("Sent: " + data);
}
我必须监听发送到49320端口的数据,然后在浏览器中进行处理。
我可以用Node.js在网页上创建一个监听器,如下所示,但我必须单独启动此服务,并在客户端上安装Node.js。
有其他选择吗更轻便的?
我也可以创建一个AJAX,每2秒查询一次Web服务,这与Windows服务的功能相同,但似乎很多查询都是免费发送的。
//websocket gateway on 8070
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs');
var mysocket = 0;
app.listen(8070);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
console.log('index.html connected');
mysocket = socket;
});
//udp server on 49320
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("msg: " + msg);
if (mysocket != 0) {
mysocket.emit('field', "" + msg);
mysocket.broadcast.emit('field', "" + msg);
}
});
server.on("listening", function () {
var address = server.address();
console.log("udp server listening " + address.address + ":" + address.port);
});
server.bind(49320);
使用Signal R。这是一种自动协商将事件从服务器推送到浏览器(如Forever Frames、Web Sockets)的最高效传输的技术,如果需要,它将回到您在问题中提到的轮询方法。我认为这是使用原始UDP的更好方法,因为所有的低级别工作都已为您完成。
以下是从windows服务中使用Signal R的示例:https://code.msdn.microsoft.com/windowsapps/SignalR-self-hosted-in-6ff7e6c3
从这个例子中,这里有一个更简单的SignalR使用OWIN自托管(没有IIS)的例子:
using System;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
namespace SignalRWindowsService
{
static class Program
{
static void Main()
{
string url = "http://localhost:8080";
WebApp.Start(url);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
//This means you can access the web sockets from the local service (on a different URL) than the domain the page in the browser was served up from.
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
public class MyHub : Hub
{
public void Send(string name, string message)
{
Clients.All.addMessage(name, message);
}
}
}
您需要以下NUGET包:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Cors" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.Core" version="2.0.3" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.SelfHost" version="2.0.3" targetFramework="net45" />
<package id="Microsoft.Owin" version="2.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Cors" version="2.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Diagnostics" version="2.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="2.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="2.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.SelfHost" version="2.0.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="5.0.1" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>