SignalR Clients.Caller(Clients.Caller.GroupName) does not work - asp.net-mvc

I am going through tutorials on SignalR and cannot figure out why this does not work.
This works:
Clients.Group("TestGroup").displayText(person.Name, person.Message);
This does not work:
Clients.Group(Clients.Caller.GroupName).displayText(person.Name, person.Message);
The javascript code:
var broadcaster = $.connection.groupHub;
broadcaster.client.displayText = function (name, message) {
$('#messages').append('<li>' + name + ' said:' + message + '</li>');
};
$.connection.hub.start().done(function () {
$('#broadcast').off().on("click", function () {
var group = "GroupTest";
broadcaster.server.join(group);
broadcaster.state.GroupName = group;
broadcaster.server.broadcastMessage({ Name: $('#name').val(), Message: $('#message').val() });
broadcaster.server.leave(group);
});
This doesn't make a lot of sense to me and its probably something small I am missing or doing wrong.

The problem is solved by casting to string:
Clients.Group(Clients.Caller.GroupName).displayText(person.Name, person.Message);
should be:
Clients.Group((string)Clients.Caller.GroupName).displayText(person.Name, person.Message);
I assume this is because the Clients.Caller and broadcast.state are dynamic.
The book I am reading does not mention this however, either due to an error, or a difference perhaps in versions of SignalR

Related

Print stacktrace using Frida

I'm able to sucessfully hook into an Android method using Frida, but I am trying to find out who is calling that method. I can find that out if I can rewrite the method with Frida to print the stacktrace when the method gets called. I've tried a few things, but all of them have had some sort of error. This is the latest thing I have tried.
setImmediate(function() {
console.log("[*] Starting script");
Java.perform(function () {
var Activity = Java.use("com.package.MyClass");
Activity.getUpdates.overload('boolean', 'java.lang.String', 'java.lang.String').implementation = function (v1, v2, v3) {
console.log("v1: " + v1);
console.log("v2: " + v2);
console.log("v3: " + v3);
Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new())
};
});
})
This is resulting in the following error
Error: Not allowed outside Java.perform() callback
at d (frida/node_modules/frida-java/index.js:86)
at frida/node_modules/frida-java/index.js:366
at [anon] (repl1.js:11)
at input:1
Any idea how I can achieve this?
I fixed it by using this:
Java.perform(function() {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()))
});
It is necessary to add an additional Java.perform call

Unable to join chat channel

When trying to join a channel in the twilio code I've been working with, it comes up with the error saying that it "Cannot read property 'getChannelByUniqueName' of null". The chat works but when I try to open it up on a different browser, like firefox instead of chrome, it says the error "Channel with provided unique name already exist". Can anyone help with this problem?
// Initialize the Chat client
chatClient = new Twilio.Chat.Client(data.token);
joinChannels(chatClient);
});
function joinChannels(chatClient) {
chatClient.getSubscribedChannels();
joinChannel('generalss','Generals Chat Channel');
}
function joinChannel(channelName, channelFriendlyName) {
console.log(channelName);
console.log(chatClient);
print('Attempting to join "' + channelName + '" chat channel...');
var promise = chatClient.getChannelByUniqueName(channelName);
promise.then(function(channel) {
console.log('Found ' + channelName + ' channel:');
channels[channelName] = channel;
console.log(channels);
setupChannel();
}).catch(function() {
// If it doesn't exist, let's create it
chatClient.createChannel({
uniqueName: channelName,
friendlyName: channelFriendlyName
}).then(function(channel) {
channels[channelName] = channel;
setupChannel(channelName);
});
});
}
Twilio developer evangelist here.
It looks to me like you aren't passing the chatClient to your joinChannel method (and secondly that the client might not be fully initialised yet).
I would initialise the client with the following, which uses the create method that returns a promise that resolves when the Client is ready.
// Initialize the Chat client
new Twilio.Chat.Client.create(data.token).then(function(chatClient) {
joinChannels(chatClient);
});
});
Then, make sure you pass the client through to the joinChannel method:
function joinChannels(chatClient) {
chatClient.getSubscribedChannels();
joinChannel(chatClient, 'generalss','Generals Chat Channel');
}
function joinChannel(chatClient, channelName, channelFriendlyName) {
// the rest...
}
Let me know if that helps at all.

Why is should.be.type() failing with "TypeError: (intermediate value).should.be.type is not a function"

I do not understand why the following test is failing with the error:
TypeError: (intermediate value).should.be.type is not a function
describe('#Option object', function() {
it('returns value as whatever type was passed to the constructor', function() {
var o = function() {
this.getValue = function() {
return new Date();
}
};
var i = new o();
i.getValue().should.be.type('Date');
})
});
I've read [most] of the Should.js documentation but I must be missing something. Can anyone tell me what is wrong with my test?
Actually only one thing wrong. You read not should.js docs, but unit.js docs - it is not related to should.js at all.
Correct link.
Correct code will be:
i.getValue().should.be.instanceOf(Date);
or
i.getValue().should.be.Date();

SignalR- send data to a specific client

I want to send data to a specific client. to do that I am trying with the following;
public Task GetWaitingOrdersCount(string id, string clientId)
{
DateTime today = Util.getCurrentDateTime();
var data = 10
return Clients.Client(Context.ConnectionId).loadOrders(data);
//return data;
}
In the above code, I want to send 'data' to the 'clientId' passed to this method.
BUT I m having an error in this line
return Clients.Client(Context.ConnectionId).loadOrders(data);
And the error is
'System.Threading.Tasks.Task<object>' does not contain a definition for 'loadOrders'
the client side code
con.loadOrders = function (data) {
loadOrders(data);
};
function loadOrders(data) {
$('#totalOrders').html(data);
}
Any help about the error???
EDIT:
This is my full client code..
<script type="text/javascript">
var con;
$(document).ready(function () {
con = $.connection.messagingHub;
$.connection.hub.start(function () {
var myClientId = $.connection.hub.id;
con.getWaitingOrdersCount('<%:ViewBag.rid%>',myClientId).done(function (data) {
console.log(data);
});
});
con.client.loadOrders = function (data) {
loadOrders(data);
};
});
function loadOrders(data) {
$('#totalOrders').html(data);
I just tried out your code (slightly modified) and it works fine for me. What version of SignalR are you using? Judging by your server code I'd say 1.0Alpha1+ but your client code looks more like 0.5.3, that is unless your con object is assigned to $.connection.yourhub.client;
If you update to SignalR 1.0Alpha2 and change your client code to be:
var con = $.connection.myCon;// This is arbitrary and would change based on your naming
con.client.loadOrders = function (data) {
loadOrders(data);
};
function loadOrders(data) {
$('#totalOrders').html(data);
}
That being said I believe your issue has to do with the version of SignalR you are using, server side that is: since you're receiving a task oriented error. Another piece of information that might be beneficial would be to know how GetWaitingOrdersCount is being called. Aka is it being invoked from the client directly via: con.server.getWaitingOrdersCount or is it being called from within the hub.
Hope this info helps!

XMLHttpRequest different in IE8 vs. FireFox/Chrome

I'm having a problem similar to jQuery $.ajax Not Working in IE8 but it works on FireFox & Chrome, but with a different use case.
I'm using the jQuery Form plug-in to handle a file upload to an ASP.NET MVC controller, which sends the file off for parsing and processing. If an Exception is thrown, it should alert the user to the issue.
//client side code
//make an ajax call, sending the contents of the file
$("#ajaxUploadForm").ajaxSubmit({
dataType: 'json',
url: '/plan/Something/ExcelImport',
iframe: true,
beforeSend: function () {
$(".ui-dialog-buttonpane").find("#my_progress").fadeIn();
},
success: function (data, textStatus) {
output = "<center><span class='flash'>" + data.message + "</span></center>";
$("#flash_message").html(output).fadeIn('slow');
setTimeout(function () { $("#flash_message").fadeOut() }, 5000);
cleanup();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("XMLHttpRequest is " + XMLHttpRequest);
var contents = "";
for (prop in XMLHttpRequest) {
contents += "\na property is " + prop + " it's value is " + XMLHttpRequest[prop];
}
alert("the contents are " + contents);
alert("textStatus is " + textStatus);
alert("errorThrown is " + errorThrown);
//comes back in an HTML envelope. This should be parsed with regex, but I can't get it to work. Dirty hack
response = XMLHttpRequest.responseText.substring(XMLHttpRequest.responseText.indexOf("<body>"));
response = response.replace("<body>", "");
response = response.replace("</body>", "");
alert("There was a problem with the upload.\r\n" + response);
},
complete: function (XMLHttpRequest, textStatus) {
$(".ui-dialog-buttonpane").find("#my_progress").remove();
something_import.dialog('close');
something_import.dialog('destroy');
}
});
//server side code
public FileUploadJsonResult ExcelImport()
{
FileUploadJsonResult result = new FileUploadJsonResult();
HttpPostedFileBase hpf = Request.Files[0] as HttpPostedFileBase;
if (hpf.ContentLength == 0)
return new FileUploadJsonResult { Data = new { message = "File contained no data" } };
String fileName = Path.GetFileName(hpf.FileName);
String timeStampedFile = fileName.Insert(fileName.IndexOf('.'),"_"+DateTime.Now.ToFileTimeUtc());
string savedFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "tempo", timeStampedFile);
hpf.SaveAs(savedFileName);
try
{
result = ProcessFile(savedFileName, Request["Id"]) as FileUploadJsonResult;
}
catch (ArgumentException e)
{
this.Response.StatusCode = 500;
this.Response.StatusDescription = System.Net.HttpStatusCode.BadRequest.ToString();
Response.Write(e.Message);
result = Json(new { message = e.Message, stackTrace = e.StackTrace }) as FileUploadJsonResult;
}
return result;
}
This works perfectly in Chrome and Firefox. In IE, the XMLHttpRequest object coming back is different:
FF:
IE:
I've been Googling around for differences between the browser implementations of XMLHttpRequest, but haven't found anything that deals specifically with this case. Stymied.
The reason this is happening is because of the iframe fallback strategy that ajaxSubmit employs. I think since the response gets posted into the iframe IE tries to figure out how to dipslay it and decides that it wants to ask you to download the response instead of just putting it in the iframe.
I came across this same situation a while ago and found an article (that I can't find now) that offered a workaround.
If you surround your json response in a textarea nobody is going to complain(IE,FF,Chrome,probably Safari) and you'll get your response parsed correctly.
E.g. if you are returning
{Id: 1, Name: 'Me'}
just return:
<textarea>{Id: 1, Name: 'Me'}</textarea>
You see now IE thinks it's html so it inserts it into the hidden iframe. Your ajaxSubmit function still gets called and parses the json correctly and then everybody's happy. :)
If you're using ASP.NET MVC you could shamelessly copy this extension method :)
public static class ControllerExtensions
{
public static ActionResult JsonSafe(this IController controller, object obj)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return new WriteResult(string.Format("<textarea>{0}</textarea>", serializer.Serialize(obj)));
}
}
The wikipedia article on XMLHttpRequest seems to give a good overview of the history behind the XMLHttpRequest. It seems Microsoft and Mozilla developed/adopted their own versions of the object and hence why you are probably seeing different properties.
Here is a link to Microsoft's implementation of the XMLHttpRequest interface members, which seem to match the properties in your alert.
Here is the a link to Mozilla's implementation of XMLHttpRequest.
So while we wait for the W3C to standardize the XMLHttpRequest you will continue to have different implementations across the browsers like you are seeing in this case.
For some added fun here is Apple's and Opera's specifications on XMLHttpRequest.

Resources