Hi there,
I am trying to establish a websockets connection between grasshopper and unity using the websockets-sharp library. The grasshopper c# script is working and I am able to establish a connection with Unity but it is not terminating the connection on boolean toggle and I am able to confirm this via netstat. It’s only when I terminate the process or completely shut down Rhino that the server is stopped. I am pasting the commented script below.
Has anyone else experienced this problem? Any help would be greatly appreciated!
using System;
using WebSocketSharp;
using WebSocketSharp.Server;
using System.Net.Sockets; // For SocketException handling
using Rhino.Geometry;
// WebSocket behavior for bi-directional communication
public class GrasshopperSocket : WebSocketBehavior
{
protected override void OnMessage(MessageEventArgs e)
{
// When a message is received from Unity
Console.WriteLine("Received from Unity: " + e.Data);
// Send response back to Unity
Send("Message from Grasshopper: " + e.Data);
}
// Custom method to send a message to the Unity client
public void SendMessageToUnity(string message)
{
Send(message);
}
}
public class WebSocketServerComponent
{
private WebSocketServer _server;
public WebSocketServerComponent(int port)
{
try
{
// Start WebSocket server at a specific port
_server = new WebSocketServer($"ws://localhost:{port}");
_server.AddWebSocketService<GrasshopperSocket>("/ghsocket");
_server.Start();
Console.WriteLine($"WebSocket server started at ws://localhost:{port}/ghsocket");
}
catch (SocketException ex)
{
// Handle socket exception, likely caused by the port being already in use
Console.WriteLine($"SocketException: Could not start server on port {port}. It may be in use.");
Console.WriteLine(ex.Message);
}
}
// Method to stop the WebSocket server
public void StopServer()
{
if (_server != null && _server.IsListening)
{
try
{
_server.Stop();
Console.WriteLine("WebSocket server stopped.");
}
catch (Exception ex)
{
Console.WriteLine("Error stopping WebSocket server: " + ex.Message);
}
finally
{
_server = null; // Clear the server reference
}
}
}
// Method to send a custom message to Unity via WebSocket
public void SendMessage(string message)
{
if (_server != null && _server.IsListening)
{
// Send message to all connected clients
foreach (var session in _server.WebSocketServices["/ghsocket"].Sessions.Sessions)
{
session.Context.WebSocket.Send(message);
}
}
}
}
// Declare WebSocket server instance and state as class-level variables
WebSocketServerComponent server = null;
bool isRunning = false;
int port = 8080; // Default port
// Main method for Grasshopper to start/stop server and send message
void ToggleWebSocketServer(bool toggleServer, string messageToSend, int portToUse)
{
// Check if the toggle button is true (pressed)
if (toggleServer && !isRunning)
{
// Start server on specified port
server = new WebSocketServerComponent(portToUse);
isRunning = true;
}
else if (!toggleServer && isRunning)
{
// Stop server
server.StopServer();
isRunning = false;
}
// Send the custom message if server is running
if (isRunning && !string.IsNullOrEmpty(messageToSend))
{
server.SendMessage(messageToSend);
}
}
// Grasshopper inputs
//bool toggleServer = false; // Button input to toggle the server
//string messageToSend = ""; // Input message to send to Unity
//int portToUse = port; // Input for port number (allow flexibility in Grasshopper)
// Call the function with Grasshopper inputs
ToggleWebSocketServer(toggleServer, messageToSend, portToUse);