I'm attempting to make a Web app that needs to communicate to a program written in C Sharp. But I can't find a good form of communication. What I need is if a user clicks something on the Web app, it will notify the C Sharp program. Also, if an event happens on the C Sharp program, it needs to alert the Web app. Both of these are going to be running on the same machine.
Right now I'm mainly focusing on the C Sharp program just periodically "asking" what the status of the Web app is.
I've tried using POST requests to the Web app and I've had a bit of success with this but I don't know how to essentially store and update a "status" on the Web App. For example, C Sharp program sends a POST/GET request asking for the status, the Web app responds with "nothing has changed" or some sort of status code. I don't know how to keep track of that status.
I've attempted using Web Sockets but I don't think it is going to be possible on the C Sharp side. However, I'm definitely open to suggestions on how this might work.
I've tried using Socket.io with Node.js but I haven't been successful at all. I have never used Node.js before so I did a few examples and I get the very basic elements of it but I cannot set up a complete web socket. Also, I could not get Socket.io to work for me at all.
I've looked into using the ReST architectural style but I'm having a hard time understanding how I would implement it. I'm using mainly AJAX on an Apache server and most of the ReST examples I saw used IIS.
One way I've been successful with this is a horrible workaround. I use 3 files to store contents, status of Web app, and status of C Sharp program. But this requires me constantly fetching files, reading them, writing a new one, and uploading it.
This is as far as I got with a websocket that uses "ws://echo.websocket.org" to simply echo the response. I don't know how to direct the messages to a C Sharp application:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
function WebSocketTest(){
var ws = new WebSocket("ws://echo.websocket.org");
var msg = document.getElementById("message").value;
ws.onopen = function(){
ws.send(msg);
alert("Message Sent: " + msg);
};
ws.onmessage = function (event){
var received_msg = event.data;
var response
if(received_msg == "1"){
response = "Some Response";
alert("Message Received: " + received_msg + "\nResponse: " + response);
}else if(received_msg == "2"){
response = "Some Response";
alert("Message Received: " + received_msg + "\nResponse: " + response);
}else if(received_msg == "3"){
response = "Some Acknowledged Response";
alert("Message Received: " + received_msg + "\nResponse: " + response);
}else{
alert("Message Received: " + received_msg);
response = "Command Not Recognized";
}
//ws.send(event.data);
};
ws.onclose = function(){
alert("Connection is closed...");
};
}
</script>
</head>
<body>
<input type="text" id="message" placeholder="Message to Send"></input>
<div id="sse">
Run WebSocket
</div>
Type in a message to send to an "echo" Web Socket.<br>
Message will be sent, Web Socket will send back the same message. <br>
</body>
</html>
The above example will echo what gets sent and if the response happens to be a 1, 2, or 3. It will also display a custom response. This may not be exactly what I want.
For Clarification:
I would like to have a C Sharp program running in the background. Some event happens that the C Sharp program captures, it will send that event to the Web App which the user will be looking at.
Also, the Web App is running and the user clicks something so the Web App needs to send some message to the C Sharp program to handle it accordingly.
The Web App that I'm speaking of is using a bunch of Javascript/Jquery/AJAX that displays a bunch of controls to the user. The C Sharp program implements these controls to do what they are supposed to do. Let me know if I need to clarify more. A lot of this is obviously very new to me so I apologize.
NOTE: I asked this question a few days ago but I am now elaborating more and including source code. I thought about just editing the previous post but it didn't have a whole lot of insight or attention so I figured it would be better to create a new post. If I should have just edited the previous post just let me know and I will do that from now on. Thanks.
Related
** JAVASCRIPT question **
I'm using regularly ajax via XMLHttpRequest. But in 1 case, I need 1 ajax call per seconds....
but long term wise and with growing number of simultaneous users, it could bloat easily...
I'm reading stuff about webRTC data channel and it seems interesting and promissing.
Here my working AJAX function as an example of how easy and there is a few lines of codes to communicate from the browser to the server and vice-versa
function xhrAJAX ( divID , param2 ) {
// random value for each call to avoid cache
var pcache = (Math.floor(Math.random() * 100000000) + 1);
// parameters
var params = "divID="+encodeURIComponent(divID)+"¶m2="+encodeURIComponent(param2);
// setup XMLHttpRequest with pcache
var xhr = new XMLHttpRequest();
xhr.open("POST", "/file.php?pcache="+pcache, true);
// setup headers
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// prepare onready scripts
xhr.onreadystatechange = function(e) { if (xhr.readyState == 4) { $("#"+divID).html(e.currentTarget.responseText) ; } }
// send the ajax call
xhr.send(params);
}
How can I "transpose" or "convert" this ajax workflow into a webRTC data channel ? in order to avoid to setup a setInterval 1000...
Note: I mean how to replace the javascript portion of the code. PHP here is only to illustrate, I don't want to do a webRTC via PHP...
Is there a simple few lines of code way to push/receive data like this ajax function ?
the answer I'm looking for is more like a simple function to push and receive
(once the connection with STUN, ICE, TURN is established and working...)
If I need to include a javascript library like jquery or the equivalent for webRTC, I'm welcoming good and simple solution.
*** The main goal is this kind of scenario :
I have a webapp : users in desktop and users within webview in Android and IOS
right now I have this workflow => ajax every 3 seconds to "tell" the main database that the user is still active and using the browser (or the app)
But I'd like to replace with this kind : when the user uses the browser => do a webrtc data chata in background between the browser and the server
While reading on the web I think that webRTC is a better solution than websocket.
** I did a bit of search and found peerjs....
https://github.com/jmcker/Peer-to-Peer-Cue-System/blob/main/send.html
I'll do some testing, but in the meantime, if someone can trow ideas, it could be fun.
Cheers
I have a small tidbit of code for my webserver on my arduino connected to an ethernet shield:
client.println("<html><head><title>ArduServ</title></head><body>");
client.print("Current Temperature: ");client.println(getTMP());
client.println("<form method=get>Input:<input type=text size=25 name=inp><input type=submit value=submit></form>");
client.println("</body></html>");
Is there a way I can update the temperature using javascript so that I don't have to redraw the page every second? I can just change the temperature?
I personally would not use the Arduino as an HTTP server for a couple of reasons.
Performance - as a micro controller, you have limited resources. Serving all of the headers and content can be expensive if you want the interaction to be real time.
Manageability - as I'm sure you're aware, it's really frustrating having to manage the source of the web page through strings in double quotes on multiple lines like that.
The Solution
I've found that the most effective way to make a web controller interface for an Arduino is to host the page somewhere on your computer locally or even on a server if you have one. Then, make the Arduino a web socket server instead of HTTP server.
This will allow you to easily communicate using the WebSocket class in JavaScript, while not having to worry about the overhead of hosting the web content.
I've used this web socket server implementation for Arduino and it works great.
Here's a basic example based on what you showed us.
Arduino
Assuming ethernet is an EthernetServer, and socket is a WebSocketServer.
// initialize the ethernet and socket server in setup() here ...
void loop(void)
{
EthernetClient client = ethernet.available();
if (client.connected() && socket.handshake(client))
{
while (client.connected())
{
String response;
// add the temperature to the response
response += getTMP();
// send the response to the JavaScript interface
socket.sendData(response);
// update every 250 milliseconds
delay(250);
}
}
// wait to let the client fully disconnect
delay(100);
}
JavaScript
// assuming you have something like <div id="temperature"></div> in the document
var temperature = document.getElementById('temperature');
// whatever IP that was assigned to the EthernetServer
var ip = '192.168.0.99';
var socket = new WebSocket('ws://'+ ip);
socket.onmessage = function(e) {
// update the temperature text
temperature.innerHTML = e.data;
};
You can find more information about JavaScript web sockets here.
I have this simple code that I'm running in arduino
char inp;
void setup(){
Serial.begin(9600);
}
void loop(){
while(Serial.available()>0){
inp = Serial.read();
Serial.print(inp);
}
Serial.print("--");
delay(200);
}
So it continiously writes "--" and if I send something to arduino it replies with that
Then I have in a js file
var strinInfo = "";
tempSerial.on("data", function(data) {
console.log("data -> " + data);
if (stringInfo.length < 37){
stringInfo += data;
}else{
io.sockets.emit("message", stringInfo);
stringInfo = ""
}
});
That sends via sockets what I got from arduino.
My problem is that, for example, if I send
"thisisanunusuallongandterriblestringofsymbolsblablablablablablabla"
There are missing characters:
---------thisisanunusuallongandterribles,
gofsymbolsblablablablabla--blabla ----,
-------------------------------------,
in this example I'm missing "trin". Is there a way of not losing that characters?
I'm starting with node so my guess is that between the time that it emits the message ... the content from that moment is gone, maybe I'm wrong.
Looking at your code, it could be a couple of things.
You may be sending data before the listener is ready, the above libs below have that solved.
The following line worries me if (stringInfo.length < 37){. If you get successive small packets of data, the packet that puts you over 37 will only print the stringInfo but will not print the data portion.
Libs that connect to Arduino:
[Johnny Five][1]
[Firmata][2]
Both programs interact with Arduinos. Firmata is the low level one with Johnny-Five running on top.
I believe it might be the issue of baud-rate.
If you are using serialport module for serial communication with Arduino than you have to set serialport baud-rate to 9600 (same as receiving side i.e. Arduino).
By default serialport baud rate is 115200.
I'm making a chat script using jQuery and JSON, but my hosting suspends it due to 'resources usage limit'. I want to know if it is possible (and how) to reduce these requests. I read one question in which they tell something about an Ajax timeout, but I'm not very good at Ajax. The code is:
function getOnJSON() {
var from;
var to;
var msg_id;
var msg_txt;
var new_chat_string;
//Getting the data from the JSON file
$.getJSON("/ajax/end.emu.php", function(data) {
$.each(data.notif, function(i, data) {
from = data.from;
to = data.to;
msg_id = data.id;
msg_txt = data.text;
if ($("#chat_" + from + "").length === 0) {
$("#boxes").append('...some stuf...');
$('#' + from + '_form').submit(function(){
contactForm = $(this);
valor = $(this + 'input:text').val();
destinatary = $(this + 'input[type=hidden]').val();
reponse_id = destinatary + "_input";
if (!$(this + 'input:text').val()) {
return false;
}
else {
$.ajax({
url: "/ajax/end.emu.php?ajax=true",
type: contactForm.attr('method'),
data: contactForm.serialize(),
success: function(data){
responsed = $.trim(data);
if (responsed != "success") {
alert("An error occured while posting your message");
}
else {
$('#' + reponse_id).val("");
}
}
});
return false;
}
});
$('#' + from + '_txt').jScrollPane({
stickToBottom: true,
maintainPosition: true
});
$('body').append('<embed src="http://cdn.live-pin.com/assets/pling.mp3" autostart="true" hidden="true" loop="false">');
}
else {
var pane2api = $('#' + from + '_txt').data('jsp');
var originalContent = pane2api.getContentPane().html();
pane2api.getContentPane().append('<li id="' + msg_id + '_txt_msg" class="chat_txt_msg">' + msg_txt + '</li>');
pane2api.reinitialise();
pane2api.scrollToBottom();
$('embed').remove();
$('body').append('<embed src="http://cdn.live-pin.com/assets/pling.mp3" autostart="true" hidden="true" loop="false">');
}
});
});
}
The limit is of 600 reqs/5 min, and I need to make it almost each second. I had a year already paid and they have no refund, also I can't modify the server, just have access to cPanel.
Well, 600 req/5 min is pretty restrictive if you want to make a request/sec for each user. Essentially, that gives you that each user will make 60 req/min. Or 300/5 min. In other words, even if you optimize your script to combine the two requests to one, at maximum you can have two users at your site ;) Not much I guess...
You have two options:
Stick with making a chat system through Ajax requests and change the hosting provider. This might be actually cheaper if you don't have the skills to do 2.
Forget about making an Ajax request to poll and potentially another to push every second. Implement something around web sockets, long-polling or even XMPP.
If you go that route, I would look at socket.io for a transparent library that uses web sockets where they are supported and has fallbacks to long polling and others for the rest. For the XMPP-way, there is the excellent Strophe.js. Note that both routes are much more complex than your Ajax requests and will require a lot of server logic changes.
I don't think that checking each second is really a good idea, in my opinion for online chat 2/3 seconds check should be far enough.
To get less request, you can also add a check on the user activity in client side, if the windows is inactive you can lengthen the checking time, going back to 2/3 seconds when the user come back active, that will allow you to save resources and requests / minutes
I'm working on a project right now that requires keeping the UI in sync with server events. I've been using long polling which does indeed reduce the number of ajax calls, but then it put's the burden on the server to listen for the event that the client is interested in, which isn't fun either.
I'm about to switch over to socket.io which I will set up as a separate push service.
existing server --> pushes to sockt.io server --> pushes to subscribing client
ggozad's response is good, I also recommend web sockets. They work only with newer browser models, so if you want to make it available on all browsers you will need a small Flash bridge (Flash can communicate with sockets very easily and also it can call JavaScript functions and be called from JavaScript). Also, Flash offers P2P if you are interested. http://labs.adobe.com/technologies/cirrus/
Also, for server side you can look into Node.js if you are a JavaScript fan like me :)
To complete my response: there is no way to make an Ajax based chat in witch you are limited to 600 requests/5 min (2 requests/second), want to make a request/second and want more than two users.
Solution: switch to sockets or P2P.
I recommend you to call that paid service from the server side using a single thread (as an API proxy). You can still poll with 600 requests/5 min in this thread. Then every client do Ajax requests to poll or long-poll to your server API proxy without limitation.
Bit of a strange one here, i have a CCTV system and contacted the manufacturers to asked if there was an API. The answer was no.
I've been trying to understand how i can take the live jpeg picture and use it in my own app (c#).
here is a link to the liveview page that displays the the live feeds; http://pastebin.com/jCp4jZRh
The line i'm interested in is;
img_buf[0].src = "ivop.get?action=live&piccnt=0&THREAD_ID=" + thd_id;
Now piccnt seems to be for stopping browsers caching the data, so this number keeps changing and thd_id seems to be the channel number. When trying to access this i get the following message;
Authentication Error:Access Denied, authentication error
Even if i log in first, then try the above url with my own contect i still retrieve the access denied message.
Heres the source to the login page; http://pastebin.com/q7nLJ4tk
heres the source to the md5.js file; http://pastebin.com/du1ggaQB
I'm just a little stuck on how to auth then display the feed, does anyone have any pointers?
thanks
I answered a similar question awhile back, and the solution ended up being that you had to set the referrer.
In any case, to find your solution, download a copy of Fiddler.
Once running, hit your camera page, and you will see several requests. When you find one of the requests for ivop.get, drag it into the request builder and execute it a second time.
If after executing it a second time it still works (check using the inspectors), then start changing the headers, removing bits one by one until you find the key element. I suspect there will either be a cookie, or referrer that is required.
Once you have figured out those elements, it should be easy to make the appropriate request in your application.
If you can post a live URL, I can help you with this.
Best guess given the limited info available: they're checking the referrer. You can check the details of the requests using Fiddler (you can even replay the request with a slightly different referrer, confirm if that's what's happening, etc). If this is it, you can set the referrer in HTTPWebRequest: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.referer.aspx
There are many possibilities, and without having access to the source code of the CCTV server, it's hard to say which one it might be.
I'd suggest popping open an HTTP Header sniffing utility (such as https://addons.mozilla.org/en-US/firefox/addon/live-http-headers/ for firefox) and watch the headers for the successful IMG request. Then replay that request using netcat or curl. Once you've got that working, try removing HTTP headers one at a time (you're probably sending some kind of session ID, HTTP Referrer, etc - these may all be important to the CCTV server)
In any case, it's almost certainly going to be important that you at least authenticate with mlogin.get and pass along the resulting session ID in subsequent requests.
Whilst this may be old - i had the same problem. The DVR requires an authenticated login with a key sent in the url during the first redirect to the login page, and the password in hex_hmac_md5. I have a python function to login and retrieve two channel images and then logout below:
def getcamimg():
baseurl = 'http://<IPADDRESS>/'
content = str(getUrl(baseurl))
x = re.search("key=(\w+)", content)
keystr = x.group(1)
key = bytes(keystr,'utf-8')
password = bytes(<YOURPASS>,'utf-8')
hmacobj = hmac.new(key,password)
hmacpass = hmacobj.hexdigest()
#-----------------------------------------------------
loginurl = baseurl + 'mlogin.get?account=<USERNAME>&passwd='+ str(hmacpass) + '&key=' + keystr + '&Submit=Login'
lcontent = str(getUrl(loginurl))
if("another administrator" in lcontent):
print("another admin online")
exit()
y = re.search('href="([\w\d\.\?=&_-]+)"',lcontent)
finalurl = baseurl + y.group(1)
z = re.search('id=(\w+)',lcontent)
thid = z.group(1)
#-----------------------------------------------------
imgurl = baseurl + "ivop.get?action=live&piccnt=1&THREAD_ID=" + thid
imgcontent = getUrl(imgurl)
ctime = datetime.datetime.today().strftime("%Y%m%d%H%M%S")
with open("chan1_"+ctime+".jpg", "wb") as file0:
file0.write(imgcontent)
#-----------------------------------------------------
chanset = "showch.set?channel=3&THREAD_ID=" + thid
getUrl(baseurl + chanset)
#-----------------------------------------------------
icontent1 = getUrl(imgurl)
with open("chan3_"+ctime+".jpg", "wb") as file1:
file1.write(icontent1)
#-----------------------------------------------------
logout = "Forcekick.set?ITSELF=1&Logout=Logout&THREAD_ID=" + thid
getUrl(baseurl + logout)
#-----------------------------------------------------
def getUrl(url):
try:
response = requests.get(url)
response.raise_for_status()
except HTTPError as http_err:
print('HTTP error occurred: '+ str(http_err))
except Exception as err:
print('Other error occurred:' + str(err))
else:
return response.content