VB.NET Remoting Programming Challenge

  • Thread starter Thread starter John Heitmuller.
  • Start date Start date
J

John Heitmuller.

I have created a very simple and short (70 lines) demo to demonstrate
how to send data between instances of the same applications running on
the same box. Here is a link to a .zip file that contains the whole
project.

http://mysite.verizon.net/johnheitmuller/SameBoxChat.zip

I have gotten this to work by using the WM_COPYDATA message and
calling the SendMessage() function in User32.dll. This satisfies my
immediate nee, but I would be really interested to see if anybody
knowledgeable about .NET Remoting could rewrite this simple demo using
Remoting. My thought is that the technique of invoking User32.dll
may not work with future OS versions.

Thanks,
John
 
My sympathies re lack of responses on best IPC practices. I've been watching
these posts hoping for some good ideas and a useful discussion. No joy.

I've tried a few non-.net things, and I've found named pipes and WM_COPYDATA
to be the least offensive. Nothing in .net has satisfied me. Remoting is/was
the way to go in recent times, but it looks like DCOM (ugh!) warmed over.
WCF is next in line to save the day, but I don't know (I am at .net 2005 fw
2), and I am dubious. I seem to recall reading about fw 3 or 3.5 providing
stream io for pipes, but I don't know anything about it. Pipes are good for
point to point, but your situation sounds like you need a broadcast.

I want a .net equivalent of an activex exe.
 
I have gotten this to work by using the WM_COPYDATA message and
calling the SendMessage() function in User32.dll. This satisfies my
immediate nee, but I would be really interested to see if anybody
knowledgeable about .NET Remoting could rewrite this simple demo using
Remoting

Which part of remoting are you having trouble with?

You could also use WCF as well, which is more or less remoting's
replacement.
 
/signed

I've had no luck finding out the "proper" way to do inter-process
communication.

..NET Remoting seems a bit abstract and lacking in useful examples.
 
Hi, thanks for your reply.
Which part of remoting are you having trouble with?

My SameBoxChat.exe example uses a single executable to handle both
sending and receiving data between applications. I like the technique
demonstrated in SameBoxChat.exe because the code is simple, there is
very little IPC processing overhead to the app, and it is very fast.

The purest in me feels that making direct calls to the User32.dll
builds in an OS dependency that may cause problems down the road. So,
what I'm looking for is a way to accomplish the same thing with a
single peer-to-peer send/receive VB.Net app using the .Net framework
to manage the interprocess communications.

I've looked at the WCF docs in VisualStudio 2008. The parts of WCF
that seem relevant to an example like SameBoxChat.exe look very
similar to Remoting under 2.0 of the .Net Framework.

I also agree with David's reply, ".NET Remoting seems a bit abstract
and lacking in useful examples." I was hoping that if it is possible
to build a simple demo of a peer-to-peer send/receive VB.Net app using
the .Net Framework, my example might prompt someone into do it. I've
been programming for 20+ years. If I cannot figure it out, its not
simple. But, I would love to be shown up and proved wrong. 8-)

Thanks,
John
 
My sympathies re lack of responses on best IPC practices. I've been watching
these posts hoping for some good ideas and a useful discussion. No joy.

I've tried a few non-.net things, and I've found named pipes and WM_COPYDATA
to be the least offensive. Nothing in .net has satisfied me. Remoting is/was
the way to go in recent times, but it looks like DCOM (ugh!) warmed over.

Remoting is much more elegant then dcom...
WCF is next in line to save the day, but I don't know (I am at .net 2005 fw
2), and I am dubious. I seem to recall reading about fw 3 or 3.5 providing

3.0 is 2.0 warmed over. You can use WCF from 2005 just fine - but it
requires framework 3.0, which is just 2.0 with some additional libraries
(actually its the same with 3.5 - it's runtime 2.0 sp1 and some
additonal stuff and a new compiler).
stream io for pipes, but I don't know anything about it. Pipes are good for
point to point, but your situation sounds like you need a broadcast.

Named pipes are supported in 3.5 (I don't think they were in 3.0).
I want a .net equivalent of an activex exe.

WCF/Remoting is yoru equivalent.
 
The purest in me feels that making direct calls to the User32.dll
builds in an OS dependency that may cause problems down the road. So,
what I'm looking for is a way to accomplish the same thing with a
single peer-to-peer send/receive VB.Net app using the .Net framework
to manage the interprocess communications.

There is no reason why in remoting you could not host the client/server
in the same .exe. Your client just needs to expose an endpoints.

Unfortunately remoting out of the box is not bidirectional, so you'll
need to build some logic in the app to handle 2-way messaging.
I've looked at the WCF docs in VisualStudio 2008. The parts of WCF
that seem relevant to an example like SameBoxChat.exe look very
similar to Remoting under 2.0 of the .Net Framework.

Similar, yet very different. WCF allows for multiple communications
channels and the ability to do bidirectional communications out of the
box.

WCF also has a Peer-to-Peer channel which maybe applicable in your
situation.
I also agree with David's reply, ".NET Remoting seems a bit abstract
and lacking in useful examples."

A bit perhaps - The company I work at use remoting extensively; it's not
mysterious once you build an application ro two.
I was hoping that if it is possible
to build a simple demo of a peer-to-peer send/receive VB.Net app using
the .Net Framework, my example might prompt someone into do it. I've
been programming for 20+ years. If I cannot figure it out, its not
simple. But, I would love to be shown up and proved wrong. 8-)

If remoting is too complex, there are alternative frameworks available
such as Genuine Channels and RemObjects.
 
Okay, since nobody took up my challenge. I've had to solve this
myself. I have written a simple but complete demo of inter-process
two-communication using named pipes implemented with version 3.5 of
the .Net Framework in VB. The complete solution can be downloaded
from here.

http://mysite.verizon.net/johnheitmuller/TxtMsg.zip

I've included all of the VisualStudio 2008 run-time libs needed to run
this example even if you do not have VS2008 installed.

Here is the source listing.

Imports System.Text ' required for UTF8Encoding
Imports System.IO
Imports System.IO.Pipes

Public Class TxtMsg
Private strPipeName As String
Private encoding As UTF8Encoding
Private pipeServer As NamedPipeServerStream
Private Const nbrTimeOut As Integer = 5000 ' 5 seconds

Private Sub TxtMsg_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
CheckForIllegalCrossThreadCalls = False ' required for
running in debugger. ConnectionCallback() runs in s separate thread
encoding = New UTF8Encoding()
Me.strPipeName = Process.GetCurrentProcess.ProcessName & "_" &
Process.GetCurrentProcess.Id

Me.UpdateStatus("Creating Named Pipe Server: " &
Me.strPipeName)
pipeServer = New NamedPipeServerStream(Me.strPipeName,
PipeDirection.In, 1, PipeTransmissionMode.Message,
PipeOptions.Asynchronous)
Me.UpdateStatus("Named Pipe Created.")

pipeServer.BeginWaitForConnection(AddressOf
ConnectionCallback, Nothing)
Me.UpdateStatus("Waiting for connection.")
End Sub

Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnSend.Click
If Not String.IsNullOrEmpty(Me.tbxMessage.Text) Then
Dim proc As Process = Process.GetCurrentProcess()
Dim strTrgProcessName = proc.ProcessName
If Me.cbxOtherInstanceInDebugger.Checked Then
strTrgProcessName &= ".vshost"
Dim processes() As Process =
Process.GetProcessesByName(strTrgProcessName)
If processes.Length > 0 Then
Dim bytesMessage() As Byte =
encoding.GetBytes(Me.tbxMessage.Text & vbCrLf)
Dim bytesProcID() As Byte =
encoding.GetBytes(proc.Id.ToString & vbCrLf)
For Each p As Process In processes
If p.Id <> proc.Id Then ' don't send to self
Dim strServerPipeName As String =
p.ProcessName & "_" & p.Id

Me.UpdateStatus("Attempting to connect to
server " & strServerPipeName & ". Timeout = " & nbrTimeOut.ToString &
" milliseconds.")
Dim pipeStream As NamedPipeClientStream = New
NamedPipeClientStream(".", strServerPipeName, PipeDirection.Out) '
"."=localhost
pipeStream.Connect(nbrTimeOut)
Me.UpdateStatus("Connection established.")

Me.UpdateStatus("Writing to server Proc ID: "
& proc.Id.ToString & ", Message: " & Me.tbxMessage.Text)
pipeStream.Write(bytesProcID, 0,
bytesProcID.Length)
pipeStream.Write(bytesMessage, 0,
bytesMessage.Length)
Me.tbxConversation.Text &=
DateTime.Now.ToLongTimeString() & ": " & proc.Id & " " &
Me.tbxMessage.Text & vbCrLf
Me.tbxMessage.Clear()
Me.UpdateStatus("Closing connection...")
pipeStream.Close()
Me.UpdateStatus("Connection closed.")
End If
Next ' next process
End If
End If
End Sub

Private Sub ConnectionCallback(ByVal ar As IAsyncResult)
Me.UpdateStatus("ConnectionCallback() fired.")
Me.pipeServer.EndWaitForConnection(ar)
Me.UpdateStatus("End Waiting for Connection.")

Dim sr As StreamReader = New StreamReader(Me.pipeServer)
Dim strProcID As String = sr.ReadLine()
Dim strMessage As String = sr.ReadLine()
Me.UpdateStatus("Received ProcID String (" & strProcID & "),
string length = " & strProcID.Length.ToString)
Me.UpdateStatus("Received Message String (" & strMessage & "),
string length = " & strMessage.Length.ToString)
Me.tbxConversation.Text &= DateTime.Now.ToLongTimeString() &
": " & strProcID & " " & strMessage & vbCrLf

Me.UpdateStatus("Disconnecting connection.")
Me.pipeServer.Disconnect()
pipeServer.BeginWaitForConnection(AddressOf
ConnectionCallback, Nothing)
Me.UpdateStatus("Waiting for connection.")
End Sub

Private Sub UpdateStatus(ByRef str As String)
Me.tbxStatus.AppendText(DateTime.Now.ToLongTimeString() & ":
" & str & vbCrLf)
End Sub
End Class
 
Back
Top