65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 UPnP 在本地局域网上推广你的应用程序 Web 界面

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.80/5 (6投票s)

2011 年 2 月 3 日

CPOL

5分钟阅读

viewsIcon

33050

downloadIcon

1265

通过提供更易于访问的 Web 界面,使应用程序更用户友好。

引言

许多应用程序都支持 Web 界面,用于控制应用程序或进行配置。例如;大多数家用路由器都有一个配置页面,或者像 eMule 这样的下载/文件共享应用程序有一个完整的应用程序 Web 界面。它们看起来可能很方便,但访问这些页面仍然很麻烦。

访问家用路由器通常需要在命令提示符下输入 ipconfig 命令来查找 IP 地址,然后可以使用该地址在浏览器中输入类似 http://123.123.123/ 的地址。eMule 使用特定的端口来访问它,因此需要一个类似于 http://123.123.123:12345/ 的 URL 来访问它,如果您使用动态 IP 地址,它可能会随着时间而改变。

如果用户可以直接打开网络,找到所有可用设备/服务的图标,并且点击一下即可访问,那该多好?无需在局域网的所有系统上放置快捷方式,也无需固定 IP 地址。本文将介绍如何通过(滥用)UPnP 设备协议来实现这一点(在 Windows 上,但这可能也适用于其他平台)。请看下面的截图,了解它是如何实现的。

本文中的代码使用了 UPnP 开发工具(以前的 Intel UPnP 堆栈)。

背景

UPnP 协议支持使用 SSDP 协议进行自动发现。Windows 支持开箱即用的 UPnP,只需打开网络就会自动显示网络上的所有 UPnP 设备(您可能需要启用 UPnP 才能显示它们)。

UPnP 设备通常提供有关设备的通用详细信息,并且(通过 UPnP 协议)可以查询它们提供的服务或嵌入的子设备。一旦从 UPnP 设备检索到设备描述(包含详细信息和服务),就可以访问服务的函数和属性。有关 UPnP 协议的更多信息,请查看 http://www.upnp.org/ 上的文档。最常见的 UPnP 实现是 mediaserver 和 mediarender 设备,如果您曾经使用 WMP 在另一台计算机上浏览媒体,或者从电视上浏览 NAS 设备上的视频收藏,您可能已经使用过 UPnP 了。

如何实现

UPnP 针对不同目的有标准设备;媒体服务器、媒体渲染器和网络网关是最常用的。UPnP 设备的最基本版本称为“basic”(一个恰当的名称)。它不定义任何服务或嵌入式设备,因此只有通用信息。通用项目之一是访问设备的演示页面。这不是必需项,因此许多设备都没有实现它。但在这个例子中,我们将使用它来提供一个简单的重定向 HTML 片段到用户实际需要的 Web 前端。

现在发生了什么

  • 用户打开网络
  • 在“其他设备”标题下显示设备
  • 用户双击图标
  • Windows 将在浏览器中打开指向 UPnP 设备(*)的链接
  • 设备页面处理程序将返回一个 HTML 重定向页面。
  • 浏览器根据重定向打开您应用程序的实际 Web 前端

(*) Windows 对不同类型的 UPnP 设备有默认行为。如果您启用了路由器上的 UPnP,它会显示在“网络基础架构”部分。但由于 Windows 对此设备类型的默认操作是“禁用”(我不知道这实际上是做什么的),双击不会打开其管理页面。所以,如果您不使用“basic”,使用具有打开 UPnP 设备 URL 的默认操作的设备类型很重要(请查看下方参考部分中的实用程序,它包含一个包含大多数已知标准设备类型的测试文件,以测试差异)。

Using the Code

首先,您的应用程序应添加对 UPnP 库的引用。然后,创建 UPnP 设备所需的代码非常简单,只需设置一组属性并调用 StartDevice

        ' Create UPnP device and set it up
        ' _objUPnPDevice is of type OpenSource.UPnP.UPnPDevice
        _objUPnPDevice = OpenSource.UPnP.UPnPDevice.CreateRootDevice(900, 1, 
            "t:\going nowhere\")
        _objUPnPDevice.HasPresentation = True
        _objUPnPDevice.StandardDeviceType = "basic"
        _objUPnPDevice.PresentationURL = "link/forward.html"
        _objUPnPDevice.AddVirtualDirectory("link", AddressOf HeaderHandler, 
            AddressOf PageHandler)
        _objUPnPDevice.UniqueDeviceName = System.Guid.NewGuid().ToString()
 
        ' The information following can be whatever you like...
        _objUPnPDevice.Manufacturer = "CodeProject"
        _objUPnPDevice.ManufacturerURL = "https://codeproject.org.cn"
        _objUPnPDevice.ModelName = "UPnP access to webinterface"
        _objUPnPDevice.ModelDescription = 
            "Network based URL shortcut available to all users on the network (subnet)"
        _objUPnPDevice.ModelURL = New Uri("https://codeproject.org.cn")
        _objUPnPDevice.ModelNumber = ""
        _objUPnPDevice.SerialNumber = ""
        _objUPnPDevice.ProductCode = ""
        ' The friendly name is the name as shown in windows explorer
        _objUPnPDevice.FriendlyName = "New UPnP icon, please customize me!"

要启动或停止设备,可以调用 _objUPnPDevice.StartDevice_objUPnPDevice.StopDevice。除此之外,唯一需要的是页面和标头处理程序。这些处理程序处理 HTTP 页面请求,并提供 HTML 重定向页面。代码如下;

    Public Shared Sub HeaderHandler(ByVal sender As OpenSource.UPnP.UPnPDevice, 
        ByVal msg As OpenSource.UPnP.HTTPMessage, 
        ByVal WebSession As OpenSource.UPnP.HTTPSession, ByVal VirtualDir As String)
    End Sub
 
    Public Shared Sub PageHandler(ByVal sender As OpenSource.UPnP.UPnPDevice, 
        ByVal msg As OpenSource.UPnP.HTTPMessage, 
        ByVal WebSession As OpenSource.UPnP.HTTPSession, ByVal VirtualDir As String)
        Dim response As New OpenSource.UPnP.HTTPMessage
        With response
            .StatusCode = 200
            .StatusData = "OK"
            .AddTag("Content-Type", "text/html")
            .BodyBuffer = System.Text.Encoding.UTF8.GetBytes( _
                      "<html><head>" & vbCrLf & _
                      "<META HTTP-EQUIV=Refresh CONTENT=""0; URL=https://codeproject.org.cn/"">" & vbCrLf & _
                      "</head><body>" & vbCrLf & _
                      "</body></html>")
        End With
        WebSession.Send(response)
    End Sub

标头处理程序为空,因为它未使用,页面处理程序仅返回一段 HTML,该 HTML 重定向到 https://codeproject.org.cn/,您应将其自定义为指向您的应用程序界面。

为了使设备表现为正常的 UPnP 设备,最好为每个会话使用相同的唯一标识符(即 _objUPnPDevice.UniqueDeviceName 属性的值)。此外,您应该坚持使用“basic”设备类型或自定义设备类型,但不要使用任何其他标准类型,除非您计划实现该设备所需的服务和子设备。

关注点

这段非常简单的代码可以大大提高用户友好性。不幸的是,Windows 不会显示 UPnP 设备图标(即使设备列出了可用图标,Windows 也会使用自己的图标)。我没有在 Windows XP 上尝试过,但在 Vista 和 Win7 上效果非常好。我创建了一个小实用程序,基本上可以让您定义任意数量的这些设备。我在我的家用服务器上运行它,以便快速访问应用程序,而无需在家里的每个客户端上安装快捷方式。这是它的样子,在“其他设备”部分列出的 6 个图标;

advertizewebinterface1.jpg

注意;“网络基础架构”部分中的“路由器”与“DD-WRT wlan 路由器”是同一个物理设备,但由于 Windows 对路由器的默认操作不是打开演示页面,我通过该实用程序添加了它。该实用程序(使用与本文提供的示例不同的代码)可以在 此处下载(包括源代码)

从安全角度来看;Web 界面本身应是安全的。如果应用程序本身不安全,只是依赖于隐藏在某个晦涩的 IP 地址和端口组合中,那么以这种方式公开应用程序显然不是一个好主意。

一个注意事项;只有当 Windows 连接到网络时,它才会显示 UPnP 设备。因此,即使是本地 UPnP 设备,在没有网络连接时也不会显示。

参考文献

历史

2011 年 2 月 3 日 初始文章

© . All rights reserved.