Thanks to @DanRathbun’s help I’ve managed to implement a much cleaner solution using the Http class rather than a ruby socket.
Works like a charm!!!
Here is the ruby class I created.
class Communicator
def initialize(connectionstring)
@connectionstring = connectionstring
@connected = false
start_listener
end
def start_listener
@connected = true
@listener = Sketchup::Http::Request.new(@connectionstring, Sketchup::Http::GET)
@listener.headers = {'Listen'=>'SketchUp'}
@listener.start do |request, response|
puts response.body
if (response.body == "")
puts "Lost connection or couldn't connect to server."
close
else
start_listener
end
end
end
def send(msg,key = "msg")
if key == "Listen" then key == "msg" end #don't let users start a listen by mistake
@request = Sketchup::Http::Request.new(@connectionstring, Sketchup::Http::GET)
@request.headers = {key=>msg}
@request.start do |request, response|
#puts "body: #{response.body}"
end
end
def close()
if @request then @request.cancel end
if @listener then @listener.cancel end
@connected = false
end
def isconnected?
return @connected
end
end
To start the connection simply use the class like this:
com = Communicator.new("http://localhost:11235/")
To send a message simply do this:
com.send 'My message to server.'
Messages from server are out put to console as they are received.
Here is the C# class if anyone is interested.
public class WebServer
{
public EventHandler OnDataAvailable;
private readonly HttpListener _listener = new HttpListener();
private Stack<string> sendmsgs = new Stack<string>();
public TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
public WebServer(string host)
{
if (!HttpListener.IsSupported)
throw new NotSupportedException(
"Needs Windows XP SP2, Server 2003 or later.");
_listener.Prefixes.Add(host);
_listener.Start();
}
public void Run()
{
ThreadPool.QueueUserWorkItem((o) =>
{
try
{
while (_listener.IsListening)
{
ThreadPool.QueueUserWorkItem((c) =>
{
var ctx = c as HttpListenerContext;
try
{
string rstr = "";
if (ctx.Request.Headers.AllKeys[0] == "Listen")
{
while (_listener.IsListening)
{
if (sendmsgs.Count > 0)
{
rstr = sendmsgs.Pop();
break;
}
}
}
else rstr = RecieveMessage(ctx.Request);
byte[] buf = Encoding.UTF8.GetBytes(rstr);
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
}
catch { } // suppress any exceptions
finally
{
// always close the stream
ctx.Response.OutputStream.Close();
}
}, _listener.GetContext());
}
}
catch { } // suppress any exceptions
});
}
public void SendMsg(string msg)
{
sendmsgs.Push(msg);
}
private string RecieveMessage(HttpListenerRequest request)
{
string msg = request.Headers[request.Headers.AllKeys[0]].ToString();
Task task = new Task(() => OnDataAvailable?.Invoke(new string[] { request.Headers.AllKeys[0], msg}, EventArgs.Empty));
task.Start(scheduler);
task.Wait();
return "read";
}
public void Stop()
{
_listener.Stop();
_listener.Close();
}
}