【问题标题】:call subroutines via URL across local network?通过本地网络的 URL 调用子程序?
【发布时间】:2013-03-28 23:39:49
【问题描述】:

我正在用 Visual Basic .NET 编写一个程序,以便在本地网络上的 PC 上执行操作。

我基本上是在寻找某种极其简单的解决方案,让我能够:

  • 通过网络浏览器从网络上的其他机器调用子例程/函数
  • 如果可能,将参数发布到 url 中(参见下面的乐观示例)
  • 允许发送 html 的响应字符串(再次参见示例)

示例: 输入http://192.168.1.72/function/argument1/argument2 将在该(本地网络)机器上运行我的winforms应用程序中的“函数”子/函数,并通过argument1和argument2(如果包括),然后将响应页面/字符串返回到请求浏览器作为反馈

谁能指出我这样做的方法?我正在寻找相当简单但可靠的东西,因为它最终可能会全天候运行

【问题讨论】:

标签: .net windows vb.net winforms


【解决方案1】:

我正在寻找一些相当简单但可靠的东西,因为它最终可能会全天候运行

我认为最简单的方法是使用 WCF 的 WebServiceHost 类:

[ServiceContract]
public class MyService
{
    [OperationContract, WebGet(UriTemplate = "/function/{argument1}/{argument2}")]
    public string AMethod(string argument1, string argument2)
    {
        return argument1 + " " + argument2;
    }
}

将此行放入应用程序的表单加载(或任何其他入口点),

var wsh = new WebServiceHost(typeof(MyService), new Uri("http://0.0.0.0/MyService"));
wsh.Open();

并从您的浏览器调用http://192.168.1.72/Myservice/function/a/b。就是这样。

----完整的工作代码----

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            var wsh = new WebServiceHost(typeof(MyService), new Uri("http://0.0.0.0/MyService"));
            wsh.Open();
        }
    }

    [ServiceContract]
    public class MyService
    {
        [OperationContract, WebGet(UriTemplate = "/function/{argument1}/{argument2}")]
        public string AMethod(string argument1, string argument2)
        {
            return argument1 + " " + argument2;
        }

        ///******** EDIT ********
        ///
        [OperationContract, WebGet(UriTemplate = "/function2/{argument1}/{argument2}")]
        public Stream F2(string argument1, string argument2)
        {
            return ToHtml("<html><h1>" + argument1 + " " + argument2 + "</h1></HtmlDocument>");
        }

        static Stream ToHtml(string result)
        {
            var data = Encoding.UTF8.GetBytes(result);

            WebOperationContext.Current.OutgoingResponse.ContentType = "text/html; charset=utf-8";
            WebOperationContext.Current.OutgoingResponse.ContentLength = data.Length;

            return new MemoryStream(data);
        }
        ///END OF EDIT
    }
}

编辑

是否可以确定请求来自的 IP 地址?

var m = OperationContext.Current
        .IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;

var address = m.Address;

有什么方法可以让 {arguments} 成为可选项?

只需从WebGet 属性中删除UriTemplate 参数。那么你的网址将是

http://1192.168.1.72/MyService/AMethod?argument1=aaaa&argument2=bbb 

如果你想让 argument2 对 ex 来说是可选的,调用 as

http://1192.168.1.72/MyService/AMethod?argument1=aaaa

argument2 将在你的方法中获得默认值。

【讨论】:

  • 谢谢,这很有魅力。一开始我在Mac上运行Windows in Parallels时遇到了一些麻烦,网络表现不佳。但是在 windows machin 上运行,它运行得非常好。谢谢
  • 是否可以让它返回一串 HTML 或我自己的 XML 以显示在浏览器中,而不是用微软的 XML 包装的文本?而不是:pastebin.com/HdPyne9u -- 理想情况下,我希望能够返回自定义 XML 数据和 HTML 页面以在浏览器中呈现?
  • @rabbitt 在我的回答中查看编辑。使用Stream,您可以返回任何结果(文本、xml、json、图像等)。只是不要忘记设置正确的 content-type。即(text/html 用于 html)
  • @14V 啊谢谢你,你帮了大忙。我不是要打扰你,但是否可以确定请求来自的 IP 地址?还有什么方法可以使 {arguments} 可选?例如。您不必包含它们,它仍然可以在上述代码示例中处理“功能”。
  • @14V 我保证这是最后一个附加问题,紧张的笑,有没有办法为这个服务添加简单的身份验证?例如。当您进入路由器门户时,它会提示您输入凭据(用户名、密码)。您可以传递给客户端程序中的 HttpWebRequest 的相同类型的凭据?
【解决方案2】:

您需要的只是某种形式的网络服务。您可能希望通过 ASP.NET Web API 使用 REST Web 服务。

不需要单独的进程间通信机制。

【讨论】:

    猜你喜欢
    • 2015-10-02
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    相关资源
    最近更新 更多