将UDP数据从Windows服务发送到同一台计算机上的浏览器运行网页

时间:2015-06-21 18:07:20

标签: c# node.js websocket socket.io windows-services

假设我在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秒查询一次与Windows服务相同的Web服务,但似乎很多查询都是一无所获。

//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);

1 个答案:

答案 0 :(得分:1)

使用Signal R.这是一种自动协商将事件从服务器推送到浏览器(例如Forever Frames,Web Sockets)的最有效传输的技术 - 它将回溯到您在问题中提到的轮询方法,如果需要。我认为这是使用原始UDP的更好方法,因为所有低级别的工作都已为您完成。

以下是从Windows服务使用Signal R的示例:   https://code.msdn.microsoft.com/windowsapps/SignalR-self-hosted-in-6ff7e6c3

从该示例 - 这是使用OWIN自我主机(没有IIS)的SignalR的更简化示例:

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>