明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

.NET 下的remoting使用。(TCP通道)

[摘要]在.NET下的remoting使用里面,很多的書上都是使用了客戶和服務(wù)器端都是使用一樣共享成員或接口的示例來做說明。而且在實(shí)際的使用中有不小的問題。 [共享代碼]share.vbImports System.windows.formsPublic Interface Iconnect '...
在.NET下的remoting使用里面,很多的書上都是使用了客戶和服務(wù)器端都是使用一樣共享成員或接口的示例來做說明。而且在實(shí)際的使用中有不小的問題。


[共享代碼]
share.vb
Imports System.windows.forms

Public Interface Iconnect '客戶端和服務(wù)器端同時(shí)共享使用一個(gè)接口
Function getName() As String
End Interface

Public Class app
Public Shared ReadOnly Property appPath() As String '提供一些應(yīng)用程序常用路徑將會(huì)在服務(wù)安裝的 Get '過程中被使用
Return Application.StartupPath
End Get
End Property

Public Shared ReadOnly Property winPath() As String
Get
Return System.Environment.GetEnvironmentVariable("windir")
End Get
End Property
End Class

[服務(wù)器端] '共倆個(gè)文件,第一個(gè)是服務(wù)文件,第二個(gè)是服務(wù)調(diào)用的功能實(shí)現(xiàn)文件
service1.vb '引用了System.Runtime.Remoting.dll文件,這是服務(wù)
Imports System.ServiceProcess
Imports System.Runtime
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels

Public Class Service1
Inherits System.ServiceProcess.ServiceBase

#Region " 組件設(shè)計(jì)器生成的代碼 "

Public Sub New()
MyBase.New()

' 該調(diào)用是組件設(shè)計(jì)器所必需的。
InitializeComponent()

' 在 InitializeComponent() 調(diào)用之后添加任何初始化

End Sub

'UserService 重寫 dispose 以清理組件列表。
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

' 進(jìn)程的主入口點(diǎn)
<MTAThread()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase

' 在同一進(jìn)程中可以運(yùn)行不止一個(gè) NT 服務(wù)。若要將
' 另一個(gè)服務(wù)添加到此進(jìn)程,請(qǐng)更改下行以
' 創(chuàng)建另一個(gè)服務(wù)對(duì)象。例如,
'
' ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService}
'
ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1}

System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub

'組件設(shè)計(jì)器所必需的
Private components As System.ComponentModel.IContainer

'注意: 以下過程是組件設(shè)計(jì)器所必需的
' 可以使用組件設(shè)計(jì)器修改此過程。
' 不要使用代碼編輯器修改它。
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
'
'Service1
'
Me.ServiceName = "Server"

End Sub

#End Region

Protected Overrides Sub OnStart(ByVal args() As String)
' 在此處添加啟動(dòng)服務(wù)的代碼。此方法應(yīng)設(shè)置具體的操作
' 以便服務(wù)可以執(zhí)行它的工作。
Try
Dim ch As New Tcp.TcpChannel(8212) '監(jiān)聽端口是在8212,你可以修改該端口
ChannelServices.RegisterChannel(ch) '注冊(cè)端口
Remoting.RemotingConfiguration.RegisterWellKnownServiceType(Type.GetType("serviceShare.serviceShare,serviceShare", True, True), "server", WellKnownObjectMode.Singleton)

'Type.GetType中的String是需要引用的服務(wù)所在的位置,"serviceShare.serviceShare,serviceShare" 中前面?zhèn)z個(gè)serviceShare是指服務(wù)所在的程序集中的要做服務(wù)的類。逗號(hào)后面的serviceShare是指該程序集位于的文件。后面的第三個(gè)參數(shù):True就是表示要搜索該文件時(shí)不區(qū)分大小寫。"server"表示服務(wù)的名稱。

Catch ex As Exception
EventLog.WriteEntry("日志 " & ex.Message)
End Try

End Sub

Protected Overrides Sub OnStop()
' 在此處添加代碼以執(zhí)行停止服務(wù)所需的關(guān)閉操作。
Try
Dim ch As New Tcp.TcpChannel(8212)
ChannelServices.UnregisterChannel(ch)
Catch ex As Exception
EventLog.WriteEntry("日志 " & ex.Message)
End Try

End Sub

End Class

serviceShare.vb '該文件為接口的實(shí)現(xiàn)文件,可以修改這個(gè)文件獲得自己需要的服務(wù),可以在這里引用  '其他DLL中的方法
Public Class serviceShare
Inherits MarshalByRefObject
Implements share.Iconnect
Private shared i As Int32 = 0

Public Function getName() As String Implements share.Iconnect.getName
i = i + 1
Return "from Server " & i
End Function
End Class

[客戶端]
form1.vb
Imports System
Imports System.Runtime
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels

Public Class Form1
Inherits System.Windows.Forms.Form
Private ch As Tcp.TcpChannel

#Region " Windows 窗體設(shè)計(jì)器生成的代碼 "

Public Sub New()
MyBase.New()

'該調(diào)用是 Windows 窗體設(shè)計(jì)器所必需的。
InitializeComponent()

'在 InitializeComponent() 調(diào)用之后添加任何初始化

End Sub

'窗體重寫 dispose 以清理組件列表。
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Windows 窗體設(shè)計(jì)器所必需的
Private components As System.ComponentModel.IContainer

'注意: 以下過程是 Windows 窗體設(shè)計(jì)器所必需的
'可以使用 Windows 窗體設(shè)計(jì)器修改此過程。
'不要使用代碼編輯器修改它。
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Button1 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.Label1 = New System.Windows.Forms.Label
Me.Button1 = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(80, 50)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(125, 25)
Me.Label1.TabIndex = 0
Me.Label1.Text = "Label1"
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(105, 195)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(75, 25)
Me.Button1.TabIndex = 1
Me.Button1.Text = "Button1"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)
Me.ClientSize = New System.Drawing.Size(292, 273)
Me.Controls.Add(Me.Button1)
Me.Controls.Add(Me.Label1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim serverName As String
Dim aa As share.Iconnect
serverName = "tcp://127.0.0.1:8212/server"
aa = CType(Activator.GetObject(Type.GetType("share.Iconnect,share", True, True), serverName), share.Iconnect)
'注意這個(gè)地方
Label1.Text = aa.getName()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ch = New Tcp.TcpChannel '客戶端可以不注冊(cè)端口
ChannelServices.RegisterChannel(ch)
End Sub
End Class

[服務(wù)安裝]
Strart.vb '服務(wù)安裝
Module Strart
Sub Main(ByVal arg() As String)
On Error Resume Next
#If DEBUG Then
If IO.File.Exists("setup.bat") Then '批處理附后面
Shell("setup.bat", , True)
End If
#End If
If (IO.File.Exists("testService.exe")) Then
Shell(share.app.winPath & "\Microsoft.NET\Framework\v1.1.4322\InstallUtil.exe " _
& share.app.appPath & "\testService.exe /LogFile", AppWinStyle.Hide, True)
Dim Sc2 As New System.ServiceProcess.ServiceController("server")
If Sc2.Status = ServiceProcess.ServiceControllerStatus.Stopped Then
Sc2.Start()
End If
End If
End Sub
End Module

[服務(wù)卸載]
UnSetup.vb
Module strart
Sub Main()
On Error Resume Next
If (IO.File.Exists("testservice.exe")) Then
Dim Sc1 As New System.ServiceProcess.ServiceController("server")
If Sc1.Status = ServiceProcess.ServiceControllerStatus.Running Then
Sc1.Stop()

End If
Shell(share.app.winPath & "\Microsoft.NET\Framework\v1.1.4322\InstallUtil.exe /u " _
& share.app.appPath & "\testservice.exe /LogFile", AppWinStyle.Hide, True)
End If
End Sub
End Module

[批處理]
copy ..\..\serviceShare\bin\serviceShare.dll .\serviceShare.dll
copy ..\..\test\bin\test.exe .\test.exe
copy ..\..\shared\bin\share.dll .\share.dll
copy ..\..\UnSetup\bin\UnSetup.exe .\UnSetup.exe
copy ..\..\testService\bin\testService.exe .\testService.exe

這樣能方便的擴(kuò)展自己的功能,因?yàn)楹芏鄷系拇a,使用都是抄微軟的,如果程序是分開獨(dú)立制作,只公布接口的話,安微軟的做法就很難成功。


示例雖然是在一個(gè)程序中實(shí)現(xiàn)的,但在倆個(gè)程序里面也不會(huì)有問題,大家可以自己試。


點(diǎn)擊下載所需代碼