Author:水如烟
示图:
首先说一下,利用这个Dll做一个聊天程序是很方便的,通过设置ServiceInformation的CludeMachines和NotCludeMachines可以实现私聊和群聊。
这个工程有四个项目,Base.Dll,Server.Dll,Host.exe,Client.exe
项目Base提供公用信息,Client和Host都引用到。两个文件:MessageCommon.vb,MyServiceInformations.vb
文件MyServiceInformations.vb,配置信息
MyServiceInformations类在服务端(即宿主机)一经运行,即生成ServiceInformation.bin文件,当然对它可以编辑。部署客户端时将此文件附到发布包即可。如果服务端的地址改变了,也可以将其重新编辑。这里对这个二进制文件的编辑操作我就省略了,利用上面这个类就可以编辑信息的,只是没给编辑界面。
项目Server供Host引用,包含两个文件:MessageTimer.vb,MyTimer.vb
MessageTimer.vb,发出服务器时间
MyTimer.vb
CLient项目,只有一个文件ClientForm.vb
Host项目也只有一个文件,ServerForm.vb
示图:
首先说一下,利用这个Dll做一个聊天程序是很方便的,通过设置ServiceInformation的CludeMachines和NotCludeMachines可以实现私聊和群聊。
这个工程有四个项目,Base.Dll,Server.Dll,Host.exe,Client.exe
项目Base提供公用信息,Client和Host都引用到。两个文件:MessageCommon.vb,MyServiceInformations.vb
文件MyServiceInformations.vb,配置信息
Imports LzmTW.uRemoting
Public Class MyServiceInformations
Inherits ServiceInformationCollectionBase
Public Overrides Sub Initialize()
Dim info As ServiceInformation
info = New ServiceInformation
With info
With .Channel
.ChnlType = ChannelType.TcpChannel
.FilterLevel = Runtime.Serialization.Formatters.TypeFilterLevel.Full
.Port = "8000"
.PortName = "MyTimer"
.ServerMachine = "FK-A09-05"
End With
With .Service
.Mode = Runtime.Remoting.WellKnownObjectMode.Singleton
.ServerUri = "MyTimerServerUri"
.ServiceName = "MyTimer"
End With
End With
Me.Add(info)
End Sub
End Class
文件MessageCommon.vb,用来互通消息Public Class MyServiceInformations
Inherits ServiceInformationCollectionBase
Public Overrides Sub Initialize()
Dim info As ServiceInformation
info = New ServiceInformation
With info
With .Channel
.ChnlType = ChannelType.TcpChannel
.FilterLevel = Runtime.Serialization.Formatters.TypeFilterLevel.Full
.Port = "8000"
.PortName = "MyTimer"
.ServerMachine = "FK-A09-05"
End With
With .Service
.Mode = Runtime.Remoting.WellKnownObjectMode.Singleton
.ServerUri = "MyTimerServerUri"
.ServiceName = "MyTimer"
End With
End With
Me.Add(info)
End Sub
End Class
Public Class MessageCommon
Inherits LzmTW.uRemoting.MessageBase
Sub New(ByVal text As String)
Me.Name = "一般会话"
Me.Body = text
End Sub
End Class
Inherits LzmTW.uRemoting.MessageBase
Sub New(ByVal text As String)
Me.Name = "一般会话"
Me.Body = text
End Sub
End Class
MyServiceInformations类在服务端(即宿主机)一经运行,即生成ServiceInformation.bin文件,当然对它可以编辑。部署客户端时将此文件附到发布包即可。如果服务端的地址改变了,也可以将其重新编辑。这里对这个二进制文件的编辑操作我就省略了,利用上面这个类就可以编辑信息的,只是没给编辑界面。
项目Server供Host引用,包含两个文件:MessageTimer.vb,MyTimer.vb
MessageTimer.vb,发出服务器时间
Public Class MessageMyTimer
Inherits LzmTW.uRemoting.MessageBase
Sub New()
Me.Name = "时间服务"
Me.Body = Now
End Sub
End Class
Inherits LzmTW.uRemoting.MessageBase
Sub New()
Me.Name = "时间服务"
Me.Body = Now
End Sub
End Class
MyTimer.vb
Imports LzmTW.uRemoting
Public Class MyTimer
Inherits ServiceBase
Dim m_sendEventTimer As System.Threading.Timer
Sub New()
End Sub
Public Sub BeginServer()
Dim timerDelegate As System.Threading.TimerCallback = AddressOf SendTimeToClients
m_sendEventTimer = New System.Threading.Timer(timerDelegate, Nothing, 500, 1000)
End Sub
Private Sub SendTimeToClients(ByVal stateInfo As Object)
Me.OnSendMessage(Nothing, New MessageMyTimer)
End Sub
Public Overloads Function InitializeLifetimeService() As Object
Return Nothing
End Function
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
m_sendEventTimer.Dispose()
End If
End Sub
End Class
Public Class MyTimer
Inherits ServiceBase
Dim m_sendEventTimer As System.Threading.Timer
Sub New()
End Sub
Public Sub BeginServer()
Dim timerDelegate As System.Threading.TimerCallback = AddressOf SendTimeToClients
m_sendEventTimer = New System.Threading.Timer(timerDelegate, Nothing, 500, 1000)
End Sub
Private Sub SendTimeToClients(ByVal stateInfo As Object)
Me.OnSendMessage(Nothing, New MessageMyTimer)
End Sub
Public Overloads Function InitializeLifetimeService() As Object
Return Nothing
End Function
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
m_sendEventTimer.Dispose()
End If
End Sub
End Class
CLient项目,只有一个文件ClientForm.vb
Imports LzmTW.uRemoting
Public Class ClientForm
Inherits System.Windows.Forms.Form
Windows 窗体设计器生成的代码
Private WithEvents LocalTimer As New Windows.Forms.Timer
Private TimerServiceInfo As ServiceInformation
Private ClientFactory As ClientFactory
Private MessageIndex As Integer
Private ServerTime As Date
Private Sub ClientForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
LocalTimer.Interval = 1000
LocalTimer.Start()
End Sub
Private Sub LocalTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles LocalTimer.Tick
Me.LocalTimerLabel.Text = String.Format("本地时间:{0}", Now)
End Sub
Private Sub LinkServerButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LinkServerButton.Click
If Not ClientFactory Is Nothing Then Exit Sub
Dim ServiceInfos As New Base.MyServiceInformations
TimerServiceInfo = ServiceInfos("MyTimer")
'测试远程服务是否启动
Dim tmpService As IService = ServicesFactory.ActivatorGetObject(TimerServiceInfo)
Try
Console.WriteLine(tmpService.Information.ClientServerUri)
ClientFactory = New ClientFactory
AddHandler ClientFactory.ServiceMessageArrived, AddressOf OnMessageArrived
ClientFactory.ServiceAdd(TimerServiceInfo)
ClientFactory.ServiceEventConnect(TimerServiceInfo.Service.ServiceName)
Me.AddListViewItem("本地", "本地操作", "连接时间服务器成功")
tmpService = Nothing
Catch ex As Exception
Me.AddListViewItem("本地", "本地操作", "连接时间服务器失败")
End Try
End Sub
Private Sub TimingButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimingButton.Click
If ClientFactory Is Nothing Then Exit Sub
If Math.Abs(Now.Subtract(Me.ServerTime).TotalSeconds) > 1 Then
Microsoft.VisualBasic.TimeOfDay = Me.ServerTime
If Math.Abs(Now.Subtract(Me.ServerTime).TotalSeconds) > 1 Then
Me.AddListViewItem("本地", "本地操作", "同步时间失败")
Else
Me.AddListViewItem("本地", "本地操作", "同步时间成功")
End If
End If
End Sub
Private Sub SendMessageButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendMessageButton.Click
If ClientFactory Is Nothing Then Exit Sub
ClientFactory.MessageSendToServer(TimerServiceInfo.Service.ServiceName, Nothing, New Base.MessageCommon(Me.MessageTextBox.Text))
Me.AddListViewItem("本地", "会话发送", Me.MessageTextBox.Text)
End Sub
Private Sub OnMessageArrived(ByVal sender As Object, ByVal arg As IMessage)
If arg.Name = "时间服务" Then
Me.ServerTime = CType(arg.Body, Date)
Me.ServerTimeLabel.Text = String.Format("服务器时间:{0}", arg.Body)
Else
With arg
Me.AddListViewItem(.Machine, .Name, .Body)
End With
End If
End Sub
Private Sub AddListViewItem(ByVal Address As String, ByVal SourceClass As String, ByVal Text As String)
MessageIndex += 1
Dim Items(3) As String
Items(0) = MessageIndex
Items(1) = Address
Items(2) = SourceClass
Items(3) = Text
Me.MessageListView.Items.Insert(0, New Windows.Forms.ListViewItem(Items))
End Sub
End Class
Public Class ClientForm
Inherits System.Windows.Forms.Form
Windows 窗体设计器生成的代码
Private WithEvents LocalTimer As New Windows.Forms.Timer
Private TimerServiceInfo As ServiceInformation
Private ClientFactory As ClientFactory
Private MessageIndex As Integer
Private ServerTime As Date
Private Sub ClientForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
LocalTimer.Interval = 1000
LocalTimer.Start()
End Sub
Private Sub LocalTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles LocalTimer.Tick
Me.LocalTimerLabel.Text = String.Format("本地时间:{0}", Now)
End Sub
Private Sub LinkServerButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LinkServerButton.Click
If Not ClientFactory Is Nothing Then Exit Sub
Dim ServiceInfos As New Base.MyServiceInformations
TimerServiceInfo = ServiceInfos("MyTimer")
'测试远程服务是否启动
Dim tmpService As IService = ServicesFactory.ActivatorGetObject(TimerServiceInfo)
Try
Console.WriteLine(tmpService.Information.ClientServerUri)
ClientFactory = New ClientFactory
AddHandler ClientFactory.ServiceMessageArrived, AddressOf OnMessageArrived
ClientFactory.ServiceAdd(TimerServiceInfo)
ClientFactory.ServiceEventConnect(TimerServiceInfo.Service.ServiceName)
Me.AddListViewItem("本地", "本地操作", "连接时间服务器成功")
tmpService = Nothing
Catch ex As Exception
Me.AddListViewItem("本地", "本地操作", "连接时间服务器失败")
End Try
End Sub
Private Sub TimingButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimingButton.Click
If ClientFactory Is Nothing Then Exit Sub
If Math.Abs(Now.Subtract(Me.ServerTime).TotalSeconds) > 1 Then
Microsoft.VisualBasic.TimeOfDay = Me.ServerTime
If Math.Abs(Now.Subtract(Me.ServerTime).TotalSeconds) > 1 Then
Me.AddListViewItem("本地", "本地操作", "同步时间失败")
Else
Me.AddListViewItem("本地", "本地操作", "同步时间成功")
End If
End If
End Sub
Private Sub SendMessageButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendMessageButton.Click
If ClientFactory Is Nothing Then Exit Sub
ClientFactory.MessageSendToServer(TimerServiceInfo.Service.ServiceName, Nothing, New Base.MessageCommon(Me.MessageTextBox.Text))
Me.AddListViewItem("本地", "会话发送", Me.MessageTextBox.Text)
End Sub
Private Sub OnMessageArrived(ByVal sender As Object, ByVal arg As IMessage)
If arg.Name = "时间服务" Then
Me.ServerTime = CType(arg.Body, Date)
Me.ServerTimeLabel.Text = String.Format("服务器时间:{0}", arg.Body)
Else
With arg
Me.AddListViewItem(.Machine, .Name, .Body)
End With
End If
End Sub
Private Sub AddListViewItem(ByVal Address As String, ByVal SourceClass As String, ByVal Text As String)
MessageIndex += 1
Dim Items(3) As String
Items(0) = MessageIndex
Items(1) = Address
Items(2) = SourceClass
Items(3) = Text
Me.MessageListView.Items.Insert(0, New Windows.Forms.ListViewItem(Items))
End Sub
End Class
Host项目也只有一个文件,ServerForm.vb
Imports LzmTW.uRemoting
Public Class ServerForm
Inherits System.Windows.Forms.Form
Windows 窗体设计器生成的代码
Private TimerServiceInfo As ServiceInformation
Private TimerService As Server.MyTimer
Private ServiceObj As Runtime.Remoting.ObjRef
Private ClientFactory As ClientFactory
Private MessageIndex As Integer
Private Sub StartServerButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartServerButton.Click
If Not ClientFactory Is Nothing Then Exit Sub
TimerService = New Server.MyTimer
Dim ServiceInfos As New Base.MyServiceInformations
TimerServiceInfo = ServiceInfos("MyTimer")
TimerService.Information = TimerServiceInfo
ServiceObj = ServicesFactory.ServiceMarshal(TimerService)
'启动TimerService的BeginServer
ClientFactory = New ClientFactory
AddHandler ClientFactory.ServiceMessageArrived, AddressOf OnMessageArrived
ClientFactory.ServiceAdd(TimerServiceInfo)
ClientFactory.ServiceEventConnect(TimerServiceInfo.Service.ServiceName)
CType(ClientFactory.Service(TimerServiceInfo.Service.ServiceName), Server.MyTimer).BeginServer()
Me.AddListViewItem("本地", "系统操作", "启动时间服务")
End Sub
Private Sub StopServerButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopServerButton.Click
If ClientFactory Is Nothing Then Exit Sub
ClientFactory.MessageSendToServer(TimerServiceInfo.Service.ServiceName, Nothing, New Base.MessageCommon("服务将要停止"))
TimerService.Dispose()
ClientFactory.ServiceRemove(TimerServiceInfo.Service.ServiceName)
RemoveHandler ClientFactory.ServiceMessageArrived, AddressOf OnMessageArrived
ClientFactory = Nothing
ServicesFactory.Services.Disconnect(TimerService)
ServicesFactory.ChannelUnregister(TimerServiceInfo.Channel.PortName)
ServiceObj = Nothing
TimerService = Nothing
Me.TimerLabel.Text = "时间:"
Me.AddListViewItem("本地", "系统操作", "停止时间服务")
End Sub
Private Sub SendMessageButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendMessageButton.Click
If ClientFactory Is Nothing Then Exit Sub
ClientFactory.MessageSendToServer(TimerServiceInfo.Service.ServiceName, Nothing, New Base.MessageCommon(Me.MessageTextBox.Text))
Me.AddListViewItem("本地", "会话发送", Me.MessageTextBox.Text)
End Sub
Private Sub OnMessageArrived(ByVal sender As Object, ByVal arg As IMessage)
If arg.Name = "时间服务" Then
Me.TimerLabel.Text = String.Format("时间:{0}", arg.Body)
Else
With arg
Me.AddListViewItem(.Machine, .Name, .Body)
End With
End If
End Sub
Private Sub AddListViewItem(ByVal Address As String, ByVal SourceClass As String, ByVal Text As String)
MessageIndex += 1
Dim Items(3) As String
Items(0) = MessageIndex
Items(1) = Address
Items(2) = SourceClass
Items(3) = Text
Me.MessageListView.BeginUpdate()
Me.MessageListView.Items.Insert(0, New Windows.Forms.ListViewItem(Items))
Me.MessageListView.EndUpdate()
End Sub
End Class
Public Class ServerForm
Inherits System.Windows.Forms.Form
Windows 窗体设计器生成的代码
Private TimerServiceInfo As ServiceInformation
Private TimerService As Server.MyTimer
Private ServiceObj As Runtime.Remoting.ObjRef
Private ClientFactory As ClientFactory
Private MessageIndex As Integer
Private Sub StartServerButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartServerButton.Click
If Not ClientFactory Is Nothing Then Exit Sub
TimerService = New Server.MyTimer
Dim ServiceInfos As New Base.MyServiceInformations
TimerServiceInfo = ServiceInfos("MyTimer")
TimerService.Information = TimerServiceInfo
ServiceObj = ServicesFactory.ServiceMarshal(TimerService)
'启动TimerService的BeginServer
ClientFactory = New ClientFactory
AddHandler ClientFactory.ServiceMessageArrived, AddressOf OnMessageArrived
ClientFactory.ServiceAdd(TimerServiceInfo)
ClientFactory.ServiceEventConnect(TimerServiceInfo.Service.ServiceName)
CType(ClientFactory.Service(TimerServiceInfo.Service.ServiceName), Server.MyTimer).BeginServer()
Me.AddListViewItem("本地", "系统操作", "启动时间服务")
End Sub
Private Sub StopServerButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopServerButton.Click
If ClientFactory Is Nothing Then Exit Sub
ClientFactory.MessageSendToServer(TimerServiceInfo.Service.ServiceName, Nothing, New Base.MessageCommon("服务将要停止"))
TimerService.Dispose()
ClientFactory.ServiceRemove(TimerServiceInfo.Service.ServiceName)
RemoveHandler ClientFactory.ServiceMessageArrived, AddressOf OnMessageArrived
ClientFactory = Nothing
ServicesFactory.Services.Disconnect(TimerService)
ServicesFactory.ChannelUnregister(TimerServiceInfo.Channel.PortName)
ServiceObj = Nothing
TimerService = Nothing
Me.TimerLabel.Text = "时间:"
Me.AddListViewItem("本地", "系统操作", "停止时间服务")
End Sub
Private Sub SendMessageButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendMessageButton.Click
If ClientFactory Is Nothing Then Exit Sub
ClientFactory.MessageSendToServer(TimerServiceInfo.Service.ServiceName, Nothing, New Base.MessageCommon(Me.MessageTextBox.Text))
Me.AddListViewItem("本地", "会话发送", Me.MessageTextBox.Text)
End Sub
Private Sub OnMessageArrived(ByVal sender As Object, ByVal arg As IMessage)
If arg.Name = "时间服务" Then
Me.TimerLabel.Text = String.Format("时间:{0}", arg.Body)
Else
With arg
Me.AddListViewItem(.Machine, .Name, .Body)
End With
End If
End Sub
Private Sub AddListViewItem(ByVal Address As String, ByVal SourceClass As String, ByVal Text As String)
MessageIndex += 1
Dim Items(3) As String
Items(0) = MessageIndex
Items(1) = Address
Items(2) = SourceClass
Items(3) = Text
Me.MessageListView.BeginUpdate()
Me.MessageListView.Items.Insert(0, New Windows.Forms.ListViewItem(Items))
Me.MessageListView.EndUpdate()
End Sub
End Class