Problem with WebSockets Draft - c#

I'm having some trobule with Web Sockets and Microsoft's Draft implementation. I'm using the API provided by them for the server back and as well as the Silverlight fix for browsers that don't natively support Web Sockets. The information i'm working off of comes from http://channel9.msdn.com/Events/MIX/MIX11/HTM10 and http://html5labs.interoperabilitybridges.com/prototypes/websockets/websockets/info
My code compiles okay, it starts to open the connection, then fails. Here's my backend server code (in a C# Console App)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ServiceModel.WebSockets;
namespace ChatBackend
{
class Program
{
static void Main(string[] args)
{
var host = new WebSocketsHost<MessageHandler>();
host.AddWebSocketsEndpoint("ws://localhost:4502/MessageHandler");
host.Open();
Console.ReadLine();
}
}
}
Here's the MessageHandler class:
class MessageHandler : WebSocketsService
{
public override void OnMessage(string value)
{
string returnMessage = "You just said '" + value + "'";
Console.WriteLine(value);
SendMessage(returnMessage);
}
}
This backend part seems to work fine. Here's the client end:
$(document).ready(function () {
setTimeout(connect, 2050);
});
function connect() {
websocket = new WebSocketDraft("ws://localhost:4502/MessageHandler");
websocket.onopen = function() {
websocket.send("test");
};
websocket.onclose = function () {
alert("DIED");
};
websocket.onmessage = function(event) {
sendMessage(new message(0, event.data, 0));
};
}
EDIT: I checked my firewall and allowed the port i was using. Now the connection just hangs - it doesn't close, it doesn't open. Any ideas?
EDIT 2: I did some more research, turns out i need to remove the clientaccesspolicy.xml. Also turns out i never had it, but i WAS returning a custom 302 redirect instead of a 404 not found. Fixed that, but no progress. It just hangs.
EDIT 3: Tried turning off Anti-Virus and Firewall, no change
Thanks - let me know if i need anymore code or information up here.

Can you use Firebug or something and put a breakpoint on this line in jquery.slws.js (assuming its the one you're using!)
this.slws = slCtl.Content.services.createObject("websocket");
And then step through and see where it fails ?

Your URL definitely looks like it matches the setting on your server side. It's really hard to find any examples of WebSockets actually being used since it's still such a new technology, but from what I could follow of the only working example I could find (it was on the html5labs site), I think maybe you're trying to write to the socket before it's finished opening. In the example I found, it looked like they check the readyState property of the socket, and only try to send if readyState === 1. The socket in that example gets opened by tying into the $(document).ready event, and send gets called from a button click.

Finally got this working! Turns out i had to add clientaccesspolicy.xml to the root folder of the default website on my server. I thought i had to delete it - i misread some information and promptly forgot about it. Moral of the story: read the readme!

Related

how to get real time log via perforce api similar to p4v log

I am facing issue with perforce api (.net), as i am unable to pull sync logs in real time.
- What am I trying to do
I am trying to pull real time logs as Sync is triggered using the
Perforce.P4.Client.SyncFiles() command. Similar to the P4V GUI Logs, which update when we try to sync any files.
- What is happening now
As the output is generated only after the command is done execution its not something intended for.
Also tried looking into Perforce.P4.P4Server.RunCommand() which does provide detailed report but only after the execution of the command.
Looked into this
Reason is -
I am trying to add a status update to the Tool i am working on which shows which Perforce file is currently being sync'd.
Please advise. Thanks in Advance.
-Bharath
In the C++ client API (which is what P4V is built on), the client receives an OutputInfo callback (or OutputStat in tagged mode) for each file as it begins syncing.
Looking over the .NET documentation I think the equivalents are the P4CallBacks.InfoResultsDelegate and P4CallBacks.TaggedOutputDelegate which handle events like P4Server.InfoResultsReceived etc.
I ended up with the same issue, and I struggled quite a bit to get it to work, so I will share the solution I found:
First, you should use the P4Server class instead of the Perforce.P4.Connection. They are two classes doing more or less the same thing, but when I tried using the P4.Connection.TaggedOutputReceived events, I simply got nothing back. So instead I tried with the P4Server.TaggedOutputReceived, and there, finally, I got the TaggedOutput just like I wanted.
So, here is a small example:
P4Server p4Server = new P4Server(cwdPath); //In my case I use P4Config, so no need to set user or to login, but you can do all that with the p4Server here.
p4Server.TaggedOutputReceived += P4ServerTaggedOutputEvent;
p4Server.ErrorReceived += P4ServerErrorReceived;
bool syncSuccess=false;
try
{
P4Command syncCommand = new P4Command(p4Server, "sync", true, syncPath + "\\...");
P4CommandResult rslt = syncCommand.Run();
syncSuccess=true;
//Here you can read the content of the P4CommandResult
//But it will only be accessible when the command is finished.
}
catch (P4Exception ex) //Will be caught only when the command has failed
{
Console.WriteLine("P4Command failed: " + ex.Message);
}
And the method to handle the error messages or the taggedOutput:
private void P4ServerErrorReceived(uint cmdId, int severity, int errorNumber, string data)
{
Console.WriteLine("P4ServerErrorReceived:" + data);
}
private void P4ServerTaggedOutputEvent(uint cmdId, int ObjId, TaggedObject Obj)
{
Console.WriteLine("P4ServerTaggedOutputEvent:" + Obj["clientFile"]); //Write the synced file name.
//Note that I used this only for a 'Sync' command, for other commands, I guess there might not be any Obj["clientFile"], so you should check for that.
}

Xamarin says "Allow Multiple Bind To Same Port only allowed on Windows". What do I do?

I'm trying to use SocketLite.PCL with my iOS/Android solution in Xamarin,
but I get the message Allow Multiple Bind To Same Port only allowed on Windows when running it.
What does it mean and how do I fix it?
EDIT:
Example code I'm using can be found here: https://github.com/1iveowl/SocketLite.PCL
I put the following code inside rotected async override void OnStart(){} of the app:
var udpReceived = new UdpSocketReceiver();
await udpReceived.StartListeningAsync(4992, allowMultipleBindToSamePort: true);
var udpMessageSubscriber = udpReceived.ObservableMessages.Subscribe(
msg =>
{
System.Console.WriteLine($"Remote adrres: {msg.RemoteAddress}");
System.Console.WriteLine($"Remote port: {msg.RemotePort}");
var str = System.Text.Encoding.UTF8.GetString(msg.ByteData);
System.Console.WriteLine($"Messsage: {str}");
},
ex =>
{
// Exceptions received here
}
);
EDIT 2:
Ok, so setting allowMultipleBindToSamePort to false stopped that error.
Now I get the error Address already in use.
However I am still curious as to what allowMultipleBindToSamePort is used for.
As you can see in the new documentation:
IMPORTANT: Please notice that the parameter allowMultipleBindToSamePort will only work on Windows. On other platforms it should be set to false
About However I am still curious as to what allowMultipleBindToSamePort is used for.
There is a good and complete explanation on this post, you can read more in the following stackoverflow post

Native messaging from chrome extension to native host written in C#

I'm trying to receive a message from my chrome extension via native messaging. The popup.html console indicates that the message is being sent, but my host is not receiving it for some reason. I can see that the host native.exe is being launched in task manager, but the host is not receive the sent data.
popup.js
document.addEventListener('DOMContentLoaded', function() {
var downloadButton= document.getElementById('Button');
downloadButton.addEventListener('click', function () {
chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "myScript.js"}, function (data) {
sendNativeMessage(data[0]);
});
});
});
});
function sendNativeMessage(msg) {
var hostName = "com.google.example";
console.log("Connecting to host: " + hostName);
port = chrome.runtime.connectNative(hostName);
message = {"text": msg};
port.postMessage(message);
console.log("Sent message: " + JSON.stringify(message));
}
Now, when I send the message from my Chrome Extension, I can see the console log for popup.html and the message is correct.
I tried to test everything by using some code that someone claimed to have worked, from Native Messaging Chrome. Specifically, I have
native.exe
static void Main(string[] args) {
while (OpenStandardStreamIn() != null || OpenStandardStreamIn() != "")
{
Console.WriteLine(OpenStandardStreamIn());
}
}
private static string OpenStandardStreamIn()
{
//Read first four bytes for length information
System.IO.Stream stdin = Console.OpenStandardInput();
int length = 0;
byte[] bytes = new byte[4];
stdin.Read(bytes, 0, 4);
length = System.BitConverter.ToInt32(bytes, 0);
string input = "";
for (int i = 0; i < length; i++)
input += (char)stdin.ReadByte();
return input;
}
I'm still trying to wrap my head around nativeMessaging, but since I can see the message being sent via the console logs, I have to assume the error is with my .exe. I have created the registry keys, HKCU, and created the host's manifest.json file. Since the extension is launching the .exe, I'm pretty sure all of that is working fine as well.
If anyone could provide some assistance with this, that would be much appreciated. Thanks!
EDIT: After changing absolutely nothing, I cannot get my native.exe to launch anymore from my extension. In an effort to fix this, I tried rewriting my sender to not open a port:
...
chrome.tabs.executeScript(tabs[0].id, {file: "myScript.js"}, function (data) {
chrome.runtime.sendNativeMessage('com.google.example', {"text":data[0]}, function(response) {
if (chrome.runtime.lastError)
console.log("ERROR");
} else {
console.log("Response: " + response);
}
});
});
...
This doesn't work at all either. I have no idea what I'm doing wrong, or why my host .exe stopped launching when I sent a message from my extension.
EDIT #2
Good news!
I deleted my registry key and then added it again, this time into the Local Machine registry (i.e. HKLM). Again, I used the code from Native Messaging Chrome to send and receive from my host. Now, when I look at my extension's log, I can see the correct response from my host. I am using the "no-port" method by simply calling chrome.runtime.sendNativeMessage(...), which is fine for my purposes. Unfortunately, I am not receiving the message FROM the extension TO the host. Also, my host.exe never exits, even after the message has been received. I'm not sure why, but if anyone can help out, I would appreciate it.
In my host, I'm attempting to write the incoming message to a file just to test that I'm getting the message:
System.IO.File.WriteAllText(#"path_to_file.txt", OpenStandardStreamIn());
Note: The message that I'm passing FROM the extension TO the host is around 250KB (it varies from message to message).
The problem is:
Nothing is written to the file. It's completely blank.
The file takes a long time to create (~4 seconds).
My host.exe instance never terminates. It's still running (I can view it in the task manager).
In order to get my extension working, I followed the following steps:
I deleted my registry key and then re-added it in my HKLM registry.
Although unnecessary,host.exe really only needed to receive one message from the extension, so I changed my previous "open port" messaging to a "no port" message, i.e.
chrome.runtime.sendNativeMessage(...);
Importantly, when I changed the text I was sending from {"text":data[0]} to a simple string {"text":"Hello from Chrome!"}, everything began working smoothly. data[0] was a string of about 250KB, which should definitely be an acceptable message size according to the developer's site. However, I have created a different question for this problem, as I was able to solve the general message sending and receiving problem I was experiencing.

Configuring client and server using OSC in Unity

I'm trying to utilize a library for Unity called UnityOSC, which allows you to receive OSC messages, presumably, from other applications. I have an application which transmits data via UDP at the following address:
host: 127.0.0.1
port: 33433
I now need to configure UnityOSC to listen for that data. The library has a script called OSCHandler.cs, and in the init function, you can set up your client and server. I'm just not sure how to set this up.
Currently, I'm attempting this:
public void Init()
{
CreateClient("FaceClient", IPAddress.Parse("127.0.0.1"), 33433);
CreateServer("FaceServer", 6666);
}
I've matched the client parameters to those of the application transmiting the data, and the server is just random - but honestly I'm not sure what to put in either one of these. Theoretically, if I set the client / server up properly, I should be able to register information in my update function like this:
void Update() {
OSCHandler.Instance.UpdateLogs();
//clients = OSCHandler.Instance.Clients;
servers = OSCHandler.Instance.Servers;
foreach(KeyValuePair<string, ServerLog> item in servers)
{
// If we have received at least one packet,
// show the last received from the log in the Debug console
if(item.Value.log.Count > 0)
{
int lastPacketIndex = item.Value.packets.Count - 1;
UnityEngine.Debug.Log(String.Format("SERVER: {0} ADDRESS: {1} VALUE 0: {2}",
item.Key, // Server name
item.Value.packets[lastPacketIndex].Address, // OSC address
item.Value.packets[lastPacketIndex].Data[0].ToString())); //First data value
}
}
}
But so far nothing is registering to the debugger. Any idea what I'm doing wrong?
Two things, keeping in mind I did this from the command line and not in the Unity editor so things might be different.
First, line 50 in OSCPacket.cs throws an exception in the command line version. Not sure if Unity picks up Trace.Assert or not but nothing is hurt by removing the line:
Trace.Assert(string.IsNullOrEmpty(_address) == false);
I'm guessing the UnityOSC author meant to do something like:
Trace.Assert(string.IsNullOrEmpty(value) == false);
Otherwise I'm not sure how that assertion would pass since OSCMessage, a derived class of OSCPacket, directly calls the Address property in its ctor.
Secondly, if you're trying to test this on a local machine, your ports need to match:
public void Init()
{
CreateServer("Server", 5555);
CreateClient("Client", IPAddress.Parse("127.0.0.1"), 5555);
}
Lastly, my manual creation:
OSCHandler handler = new OSCHandler();
handler.Init();
handler.SendMessageToClient<string>("Client", "127.0.0.1", "TestMessage");
handler.UpdateLogs();
I had to slightly modify the authors code to get it to work outside of Unity but only slightly.
I went a different route to get this working in Unity - based off of an older project called openTSPS from James George. You can download it here - it accepts all OSC data:
https://github.com/heaversm/UnityOSC_FS

Simple Selenium Test Gives XHR ERROR : 404

I'm using selenium-rc with C# to test my asp.net mvc2 application. Currently all I am doing is opening the home page with selenium RC.
when I run my test I see the selenium remote control open in a browser and I see my application open correctly in a browser but selenium shows a 404 error and aborts the test.
In an attempt to get this working I have cut the test down to a simple console app and have changed the default selenium port here is my code:
static void Main(string[] args)
{
try
{
var _selenium = new DefaultSelenium("localhost", 1234, "*chrome", "http://localhost:6666");
_selenium.Start();
_selenium.Open("/");
try
{
_selenium.Stop();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("Done.");
Console.ReadKey();
}
this fails with the error "XHR ERROR: URL = /localhost:6666/ Response_Code = 404 Error_Message = Not Found on session 5f2e59798ae74e7cb741d50cae7e817a"
and if you look in the running selenium console you see
15:53:16.238 INFO - Allocated session 5f2e59798ae74e7cb741d50cae7e817a for http://localhost:6666, launching...
15:53:16.265 INFO - Preparing Firefox profile...
15:53:18.325 INFO - Launching Firefox...
15:53:20.977 INFO - Got result: OK,5f2e59798ae74e7cb741d50cae7e817a on session 5f2e59798ae74e7cb741d50cae7e817a
15:53:20.980 INFO - Command request: open[/, ] on session 5f2e59798ae74e7cb741d50cae7e817a
15:53:22.654 INFO - Got result: XHR ERROR: URL = http://localhost:6666/ Response_Code = 404 Error_Message = Not Found on session 5f2e59798ae74e7cb741d50cae7e817a
Interesting things that I have tried are:
change the site to "google" - then my test works
change the site to "google" port 80 then it doesnt work.
moved my site from cassini to iis 7 - didnt work
made my site the default site on iis 7 eg http://localhost/ - didnt work
I've used fiddler to watch the session - all requests fired return successfully.
I've tried passing -avoidProxy and -ensureCleanSession when starting the RC server. Hasn't made any noticable difference.
If I reconfigure selenium to use the default port I get the following exception repeated over and over (once every 10 seconds / different sessionid each time). This doesn't happen once I've changed the default port but i've included it just in case.
16:26:38.019 WARN - POST /selenium-server/driver/?seleniumStart=true&localFrameAddress=top&seleniumWindowName=&uniqueId=sel_48694&sessionId=a87b8d6a9e444a5485a5044ef6370e2d&counterToMakeURsUniqueAndSoStopPageCachingInTheBrowser=1286810798016&sequenceNumber=4115 HTTP/1.1
java.lang.RuntimeException: sessionId a87b8d6a9e444a5485a5044ef6370e2d doesn't exist; perhaps this session was already stopped?
at org.openqa.selenium.server.FrameGroupCommandQueueSet.getQueueSet(FrameGroupCommandQueueSet.java:220)
at org.openqa.selenium.server.SeleniumDriverResourceHandler.handleBrowserResponse(SeleniumDriverResourceHandler.java:165)
at org.openqa.selenium.server.SeleniumDriverResourceHandler.handle(SeleniumDriverResourceHandler.java:131)
at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1530)
at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1482)
at org.openqa.jetty.http.HttpServer.service(HttpServer.java:909)
at org.openqa.jetty.http.HttpConnection.service(HttpConnection.java:820)
at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986)
at org.openqa.jetty.http.HttpConnection.handle(HttpConnection.java:837)
at org.openqa.jetty.http.SocketListener.handleConnection(SocketListener.java:245)
at org.openqa.jetty.util.ThreadedServer.handle(ThreadedServer.java:357)
at org.openqa.jetty.util.ThreadPool$PoolThread.run(ThreadPool.java:534)
Can anybody shed some light?
I am using C# and had similar problem with selenium.open method. I have refered the thread haroonzone posted in his answer above. and have made following changes in my code
Declare selenium as
private DefaultSelenium selenium;
instead of
private ISelenium selenium;
and call open method as
selenium.Processor.DoCommand("open", new String[] { YOUR_URL, "true" });
instead of
selenium.Open("YOUR_URL");
Additionally, you may want to call
selenium.SetTimeout("600000");
before DoCommand
What version of Selenium Server are you using? We get this problem with Selenium Server 2.0a2. It is fixed in later versions of Selenium, so if you download the latest version of the Selenium Server and run this test against it then you wont get the XHR exception. But if you cannot update the selenium version then you can do the following. The code snippet is in Java you can have a similar in C#.
The problem is with the selenium.open method. You can find more information on the following URL.
http://code.google.com/p/selenium/issues/detail?id=408
selenium = new DefaultSelenium("localhost", port, browserString, url) {
public void open(String url) {
commandProcessor.doCommand("open", new String[] {url,"true"});
}
};

Categories