Quantcast
Channel: Xojo Programming Forum - Latest topics
Viewing all articles
Browse latest Browse all 3791

Advertise your Linux app on the network

$
0
0

You may know that we have plenty of classes for Bonjour on macOS, iOS and Windows. For Linux we have the Avahi classes to browser for services. In our plugin version 25.1 we add new Avahi classes to register a service. What you use this for?

You may do an application for your Raspberry Pi to run there as a service. How to find the IP to connect over the network? If you use Avahi, your application can start the ServerSocket and get the port it uses. Then advertise this on the network and your other application on a different computer and look for the service and learn what IP and port to connect this. All automatically for IPv4 as well as IPv6.

Initialize Avahi Client

In our example project we subclass AvahiClientMBS class with our AvahiClient class to implement the events. The client class provides a lot of global functionality like asking for the version of the library. And it provides the events for the overall activity to tell you if the client is running.

Let’s start with making a client object. We don’t like it to fail if the daemon is not yet running, so we pass the flag for this. We do check if the library is available and complain if not. That happens if you run the code on macOS, Windows or iOS. Or of course if the package for Linux is not installed.

Sub Start()
	client = New AvahiClient(AvahiClientMBS.kClientNoFail)
			
	If Not client.Available Then
		System.DebugLog "Avahi not found!?"
		Return
	End If
			
	System.DebugLog "Version: "+client.Version		
End Sub

For our example the events are just nice to have. You don’t need to implement them, but the example does and logs them to the console.

Class AvahiClient Inherits AvahiClientMBS
	EventHandler Sub Collision()
		System.DebugLog CurrentMethodName
	End EventHandler
	EventHandler Sub Connecting()
		System.DebugLog CurrentMethodName
	End EventHandler
	EventHandler Sub Failure(error as string, errorcode as integer)
		System.DebugLog CurrentMethodName+" "+errorcode.ToString+": "+error
	End EventHandler
	EventHandler Sub Registering()
		System.DebugLog CurrentMethodName
	End EventHandler
	EventHandler Sub Running()
		System.DebugLog CurrentMethodName
	End EventHandler
End Class

Client is a property for the application, so the object stays alive until the application quits.

Register service

In order to register our example service, we create a new AvahiEntryGroupMBS object using our subclass AvahiEntryGroup. Again we subclass it to add our event handlers. Usually you just register a service name on the current host machine in the current domain with a given port number.

The group can have multiple services to be registered at once. If we added all services with the correct entries (no error), we can commit them to the background daemon. We keep the object, so the advertisements keep running.

Sub Register()
	EntryGroup = New AvahiEntryGroup(client)
	
	Const Name = "test"
	Const Type = "_http._tcp"
	Const Domain = "" // automatically
	Const Host = "" // automatically
	const port = 80
	
	EntryGroup.AddService _
			EntryGroup.kInterfaceAny, _
			EntryGroup.kProtocolAny, _
			EntryGroup.kFlagsNone, _
			Name, _
			Type, _
			Domain, _
			Host, _
			port
	
	If EntryGroup.LastError <> 0 Then
		System.DebugLog "AddService failed with error "+EntryGroup.LastError.ToString+": "+EntryGroup.LastErrorMessage
	End If
	
	System.DebugLog "IsEmpty: "+EntryGroup.isEmpty.ToString
	System.DebugLog "State: "+EntryGroup.State.ToString
	
	// now commit to send it
	EntryGroup.Commit
	If EntryGroup.LastError <> 0 Then
		System.DebugLog "Commit failed with error "+EntryGroup.LastError.ToString+": "+EntryGroup.LastErrorMessage
	End If
End Sub

Finally let’s show you the events, where we just log the state change:

Class AvahiEntryGroup Inherits AvahiEntryGroupMBS
	EventHandler Sub StateChanged(state as Integer)
		System.DebugLog CurrentMethodName+": "+state.ToString+" "+StateToText(state)
	End EventHandler
	Shared Function StateToText(state as integer) As string
		Select Case state
			
		Case kStateCollision
			Return "Collision"
			
		Case kStateEstablished
			Return "Established"
			
		Case kStateFailure
			Return "Failure"
			
		Case kStateUncommited
			Return "Uncommited"
			
		Case kStateRegistering
			Return "Registering"
					
		End Select
	End Function
End Class

Please try the new class and let us know. The classes really help to find a service from another computer. And even if you don’t have your application on Linux, please check the Bonjour classes for macOS, iOS and Windows.

4 posts - 3 participants

Read full topic


Viewing all articles
Browse latest Browse all 3791

Trending Articles