signalr chat rooms - asp.net-mvc-3

i am trying to create a chat application and i've read that signalr is a good thing to use. i looked for examples of it and so far, i've done this:
<script src="Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script src="Scripts/jquery.signalR.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
var connection = $.connection('echo');
connection.received(function (data) {
$('#messages').append('<li>' + data + '</li>');
});
connection.start();
$("#broadcast").click(function () {
connection.send($('#msg').val());
});
});
</script>
<input id="msg">
<input id="broadcast" type="button">
<ul id="messages"></ul>
this only creates a single connection. i want to create multiple chat rooms, how can i make another connection and store those connections, lets say, in a database so i can have a record of those connections.

I don't think you need multiple connctions, but for a great example you can check out jabbr.net on gitHub an opensource chatapplication build with signalR and created by the same person that created SignalR.

The great example of web-based chat using signalr and ASP.NET MVC is http://jabbr.net. It has chatrooms, commands, smiles and other useful features. Just explore its source code which is available here: https://github.com/davidfowl/JabbR

Related

HiveMQ MQTT Websocket - can't subscribe to sub topics

I have a code that subscribes whatever user inputs in a form to an MQTT broker. Everything works fine, the data get published and show in the broker. However, I can't subscribe to sub topics.
Here is the MQTT part of the code:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.hivemq.com/demos/websocket-client/js/mqttws31.js" ></script>
<script type="text/javascript">
//Create a new Client object with your broker's hostname, port and your own clientId
var client = new Messaging.Client("broker.mqttdashboard.com", 8000, "clientId-9HL7JvIJNb");
var publish = function (payload, topic, qos) {
//Send your message (also possible to serialize it as JSON or protobuf or just use a string, no limitations)
var message = new Messaging.Message(payload);
message.destinationName = "sssmarthome/";
message.qos = qos;
client.send(message);
}
var options = {
//connection attempt timeout in seconds
timeout: 3,
//Gets Called if the connection has successfully been established
onSuccess: function () {
alert("Connected");
},
//Gets Called if the connection could not be established
onFailure: function (message) {
alert("Connection failed: " + message.errorMessage);
}
};
//Attempt to connect
client.connect(options);
</script>
As you can see, the destination name is "sssmarthome/" and that is the only topic I can subscribe to.
Here is the form code:
<form id="settingsForm" method="GET">
Temperature(low, °C): <input type="text" name="templow" id="templow">
Temperature(high, °C): <input type="text" name="temphigh" id="temphigh">
Humidity(low, %): <input type="text" name="humlow" id="humlow">
Humidity(high, %): <input type="text" name="humhigh" id="humhigh"><br>
<input type="button" value="Change" onclick="submitForm()">
</form>
<script>
function submitForm(){
publish(document.getElementById("templow").value, 'sssmarthome/templow',2)
publish(document.getElementById("temphigh").value, 'sssmarthome/temphigh',2)
publish(document.getElementById("humlow").value, 'sssmarthome/humlow',2)
publish(document.getElementById("humhigh").value, 'sssmarthome/humhigh',2)
So each of the inputs has their own subtopic. But if I go to the website and fill out the form, this is what I get on the broker:
As you can see on the picture, it doesn't show the names of the sub topics, just the main topic.
I tried subscribing to the sub topics in the broker, but nothing will get published then, the only topic that works is the default destination name. Any idea how to be able to subscribe to topics and have actually stuff published on them, with proper topic and sub topic? Thank you!
Just to put this out here as an answer, per my comment:
The code below this line:
var publish = function(payload, topic, qos)
never uses 'topic'....so since you set message.destinationName = "sssmarthome/"; and then publish, your GUI is showing just that. The outcome is exactly what your code is asking for.
The fix is to change that one line to:
message.destinationName = "sssmarthome/" + topic;
This is assuming that topic is a string.

Display external application forms within Microsoft Dynamics 365

We have our own system which we need to integrate with MS Dynamics 365.For Example : In Accounts section we need to add an extra tab that loads IFrame or something that retrieves some extra information from our system.
The following are the things that I reached :
Inserting IFrame within a new Dashboard: (but it will not fetch specific account information, it will only pass the currently logged in user along with the organization name)
Unified Service Desk (USD): (we may add customization but this is a desktop app and we need it to be on web)
Microsoft flow: this would only work in the background when you create or edit an account (not sure if it has another functionality)
Extensions: Not sure how to use it to achieve the same functionality, I believe the solution may be here but I just need from where to start.
Has anybody done a similar thing before?
Thank you
You can definitely do it,
Here is how I just tried on one of my Trail Instance.
I added new Tab as you need, I called it "HTML Page"
On this Tab I added Webresource, you can add Iframe as well and call your external WebPage.
For my simple use case I created a simple HTML page as webresource in CRM and configured it to Webresource tab as below
Sample code for HTML. Dont worry about long html file. Mostly it is bla bla. What is of our importance is <body onload="myFunction()"> and then in
<script>
function myFunction() {
debugger;
alert("Account Id when from fromcontext is ");
alert(parent.Xrm.getformContext().data.entity.getId());
}
</script>
complete HTML code below
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>My first styled page</title>
</head>
<body onload="myFunction()">
<!-- Site navigation menu -->
<ul class="navbar">
<li>Home page
<li>Musings
<li>My town
<li>Links
</ul>
<!-- Main content -->
<h1>My first styled page</h1>
<p>Welcome to my styled page!
<p>It lacks images, but at least it has style.
And it has links, even if they don't go
anywhere…
<p>There should be more here, but I don't know
what yet.
<!-- Sign and date the page, it's only polite! -->
<address>Made 5 April 2004<br>
by myself.</address>
<script>
function myFunction() {
debugger;
alert("Account Id when from fromcontext is ", parent.Xrm.getformContext().data.entity.getId());
}
</script>
</body>
</html>
Also on Form Load of account I added additional Javascript. This javascript will create global variable which could be called from your webresource.
Article Link for additional Javascript
Sample code used for Javascript below
formContext=null;
function onload(executionContext){
debugger;
var formContext = executionContext.getFormContext();
Xrm.getformContext = function (){
return formContext;
};
Xrm.getParentAttribute = function (attrName) {
debugger;
return formContext.getAttribute(attrName);
};
Xrm.getParentControl = function (attrName) {
debugger;
return formContext.getControl(attrName);
};
}
Final Result will be something like below
Summary:
Create Wberesource/Iframe
Create Additiona Js on Load
Use global variable in your webresource.

Prompt User to Upload file in Dialog Flow with MS Bot Framwork v4

I have a dialog flow that will require a user to upload a file/files. I would like to prompt the user and have them click on a button to open a file browse window to select the file they want to upload. I do not want to use the file chooser in the WebChat window text entry box (Users find this confusing). Is this possible? I saw in the documentation for v3 that there is a AttachmentPrompt dialog. However in the documentation for v4 I only see it mentioned in a one liner here... https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-concept-dialog?view=azure-bot-service-4.0 however other than that which sounds promising there appears to be no documentation on this functionality.
Thanks for any help you can provide!
PromptAttachment does not define client side rendering, or client side file upload code. In order to have the WebChat control respond to a custom button, you will need to provide an Attachment Middleware for the Web Chat control, and have the bot send a custom attachment type.
Custom Attachment:
private class FileUpload : Attachment
{
public FileUpload()
: base("application/uploadAttachment") { }
}
Replying with FileUpload attachment:
var reply = activity.CreateReply("Upload a File");
reply.Attachments.Add(new FileUpload());
await connector.Conversations.SendToConversationAsync(reply);
Page hosting Web Chat:
<!DOCTYPE html>
<html>
<body>
<div id="webchat" />
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<script src="https://unpkg.com/react#16.5.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16.5.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-redux#5.0.7/dist/react-redux.min.js"></script>
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<script>
function uploadFile() {
document.querySelector('[title="Upload file"]').click();
}
</script>
<script type="text/babel">
var chatbot = new WebChat.createDirectLine({
token: 'YourToken',
webSocket: true,
});
const attachmentMiddleware = () => next => card => {
switch (card.attachment.contentType) {
case 'application/uploadAttachment':
return (<button type="button" onClick={uploadFile}>Upload file</button>);
default:
return next(card);
}
};
WebChat.renderWebChat({
directLine: chatbot,
botAvatarInitials: 'Bot',
attachmentMiddleware,
}, document.getElementById('webchat'));
</script>
</body>
</html>

Combining reCAPTCHA v2 and v3

I'm keen to use reCAPTCHA v3 for logins and stuff, but I'm unsure what to do with a 'low rating', it doesn't feel safe to deny access with no way for the user to move forward. What feels like a more complete solution would be to combine the "rating" from v3 with a puzzle challenge from v2 if the score is too low. How are other people approaching this issue?
Also, it appears that v3's grecaptcha.execute returns a similar result to v2, that is too say that it's not returning a rating, just a TOKEN which is verified in a similar way to v2?
I've code i found to demonstrate that they can both be used in the same HTML...
<!-- https://github.com/google/recaptcha/issues/279 -->
<script src="https://www.google.com/recaptcha/api.js?onload=v2_onload"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=v3_onload&render=V3_SITE_KEY"></script>
<script src='https://www.google.com/recaptcha/api.js?render=V3_SITE_KEY'></script>
<div class="g-recaptcha" data-size="invisible" data-sitekey="V2_SITE_KEY" data-callback="v2_callback"></div>
<script type="text/javascript">
function v2_onload() { console.log('v2 loaded'); }
function v3_onload() { console.log('v3 loaded'); }
function v2_callback(token) { console.log('v2 token: ' + token); }
function v3_callback(token, score) { console.log('v3 token: ' + token + " ----- " + score); }
// call these manually
function test_v2() { grecaptcha.execute(); }
function test_v3() {
grecaptcha.execute('V3_SITE_KEY' , {action:'thisIsATest' }).then(v3_callback);
}
I have concerns then that if v3 requires sever-side validation, in order to implement v2 as well, either a page reload to invoke v2 (when server-side says "low rating" then reload and enable v2) OR v3 sever-side validation could be done via an ajax call, but that feels like something that can be inspected and manipulated by a bot (grab ajax response, change 'no' to 'yes' and then have the bot call the 'callback' function itself to gain access).
Any help or suggestions would be appreciated.
It looks like there is an answer to this question on the official Frequently Asked Questions website of reCAPTCHA.
Can I run reCAPTCHA v2 and v3 on the same page?
To do this, load the v3 site key as documented, and then explicitly render v2 using grecaptcha.render.
<html>
<head>
<title>reCAPTCHA demo: Running both v2 and v3</title>
<script src="https://www.google.com/recaptcha/api.js?render=v3_site_key"></script>
<script>
grecaptcha.ready(() => {
grecaptcha.render('html_element', {
'sitekey' : 'v2_site_key'
});
});
</script>
<script>
function onSubmit() {
grecaptcha.ready(() => {
grecaptcha.execute('v3_site_key', {action: 'homepage'}).then((token) => {
...
});
});
}
</script>
</head>
</html>
Wouldn't it be simplest to just send the token with your form post and double check it server side? I know you're still possibly allowing a bot to post data into your system, but a bot that can sneak by google should be pretty rare. And the first thing your sever side logic should do is verify the token, which can't easily be faked. That said in my initial analysis of google V3(10K requests) the bot detection was solidly binary, in that all the scores were above or below .5 . Google in their documentation recommends different strategies for how to deal with suspicious traffic based on the scenario.
https://developers.google.com/recaptcha/docs/v3.

From GoogleYolo (Google Smart Lock), what does "Invalid audience" mean?

The error/warning message (written by obfuscated code from https://www.gstatic.com//mss/boq-identity//js/k=boq-identity.IdentityYoloWebModuleset.en.5jYiE0Kzqd0.O/m=yolo_frame_library/rt=j/d=1/rs=AOaEmlHvGDn8UcjjSaG2zLiaoxdbMowW7g to the console, Chrome Version 65.0.3325.162) is, "Invalid audience. Please use the Google Cloud console (https://console.developers.google.com), and create a valid OAuth2 web client."
I was following https://developers.google.com/identity/one-tap/web/get-started -- does anyone know if a single-archive fully-complete example exists anywhere? (I looked.)
My code goes as follows, and I did set https://localhost:8000 and a personal website with https as allowed origins for the client ID in question, which are where I'm testing this.
<html>
<head>
<script src="https://smartlock.google.com/client"></script>
</head>
<body>
<script>
const clientID = "...";
const authUri = "https://accounts.google.com";
window.onGoogleYoloLoad = (googleyolo) =>
{
const retrievePromise = googleyolo.retrieve(
{
supportedAuthMethods: [ authUri ],
supportedIdTokenProviders: [ { uri: authUri, clientId: clientID } ]
});
}
</script>
</body>
</html>
Moreover, I tested similar code except with googleyolo.hint then googleyolo.retrieve and the other way around. Both ways, each time I refreshed the page, it was as if I have never visited before -- and that's whether or not I was logged in to Google in Chrome. So after the hint completes, what needs done to save or store that status?
I was able to find some working examples located here -
https://www.codeproject.com/Articles/579564/JavaScript-oAuth
https://developers.google.com/identity/sign-in/web/sign-in
I setup a test script using the examples from the CodeProject link, and just commented out the pieces I did not need.
<div class="loginDiv">
<div id="googlelogin">Google</div>
</div>
<div style="clear:both;" id="userinfo"></div>
var clientId = '.....';
var scopes = 'https://www.googleapis.com/auth/plus.me';
Enjoy!

Resources