All the blogs online have been in reference to the beta with the old namespaces and use nuget packages. Im trying to get a simple low level websockets example going based on whats in the wild now and its just not working.
The client is never able to establish a connection. The error from the chrome debug console is:
"Port error: Could not establish connection. Receiving end does not exist. "
However, I know the request is being received because I put code in my ashx handler to email me at various points just to confirm the request was coming in and my task was firing etc.
Config - All Final Release Versions:
Windows Server 2012/IIS 8/ ASP.NET 4.5
My sample is based on:
http://www.asp.net/vnext/overview/whitepapers/whats-new#_Toc318097383
The handler:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.WebSockets;
using System.Net.WebSockets;
using System.Threading;
using System.Text;
using System.Threading.Tasks;
namespace myWebSocket
{
/// <summary>
/// Summary description for wsHandler
/// </summary>
public class wsHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// context.Response.ContentType = "text/plain";
// context.Response.Write("Hello World");
context.AcceptWebSocketRequest(MyWebSocketTask);
}
public async Task MyWebSocketTask(WebSocketContext context)
{
WebSocket socket = context.WebSocket;
while (true)
{
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
message.To.Add("email#address.com");
message.Subject = "Handler";
message.From = new System.Net.Mail.MailAddress("michaelo#hostcollective.com");
message.Body = string.Format("Task Launched {0}", socket.State.ToString());
System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("localhost");
smtp.Send(message);
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
// Asynchronously wait for a message to arrive from a client
WebSocketReceiveResult result =
await socket.ReceiveAsync(buffer, CancellationToken.None);
// If the socket is still open, echo the message back to the client
if (socket.State == WebSocketState.Open)
{
string userMessage = Encoding.UTF8.GetString(buffer.Array, 0,
result.Count);
userMessage = "You sent: " + userMessage + " at " +
DateTime.Now.ToLongTimeString();
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMessage));
// Asynchronously send a message to the client
await socket.SendAsync(buffer, WebSocketMessageType.Text,
true, CancellationToken.None);
}
else { break; }
}
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
As for the client, this is the simplest one based on the stuff at websockets.org
<script language="javascript" type="text/javascript">
// var wsUri = "ws://echo.websocket.org/";
var wsUri = "ws://iis8hosting.com/mikey/wshandler.ashx";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function (evt) { onOpen(evt) };
websocket.onclose = function (evt) { onClose(evt) };
websocket.onmessage = function (evt) { onMessage(evt) };
websocket.onerror = function (evt) { onError(evt) };
}
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt) {
writeToScreen("DISCONNECTED");
}
function onMessage(evt) {
writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data + '</span>');
websocket.close();
}
function onError(evt) {
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message) {
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
<h2>WebSocket Test</h2><div id="output"></div>
Anybody have any ideas or another simple sample such as this that is confirmed to work with the final release stuff. Thanks for taking the time to read and respond.
I could make your code work with some changes in your code. You may not require to do all of the below changes in your environment.
On Server side put a try catch block around SMTP code Verify context.IsWebSocketConnection is true
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(MyWebSocketTask);
}
else
{
throw new HttpException("This isn't a WebSocket request!");
}
On client side: I changed code like below based on errors i got :).
This code will work in IISExpress 8 as well.
var wsUri = "ws://<%: Request.Url.Host %>:<%: Request.Url.Port %><%:
Response.ApplyAppPathModifier("~/wshandler.ashx")
Added serverData inside form like below.
<form id="form1" runat="server">
<div id="serverData"></div>
</form>
And used it in writeToScreen() function.
function writeToScreen(message) {
var serverData = document.getElementById("serverData");
var newElem = document.createElement("p");
newElem.style.wordWrap = "break-word";
newElem.innerHTML = message;
serverData.insertBefore(newElem, serverData.firstChild);
}
onMessage() function closes the connection from client side. So only one message is sent and received.
Make sure the IE10 browser's document mode is "Standard". I used IE10 for testing your code.
Related
This is the code I'm using. How do I specify the .NET server address which should receive the image?
var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function(ev) {
var oOutput = document.querySelector("div"),
oData = new FormData(form);
oData.append("CustomField", "extra data");
var oReq = new XMLHttpRequest();
oReq.open("POST", "abcd", true);
oReq.onload = function(oEvent) {
if (oReq.status == 200) {
oOutput.innerHTML = "Uploaded!";
}
else
{
oOutput.innerHTML = "Error " + oReq.status + " occurred when trying to upload your file.<br \/>";
}
};
oReq.send(oData);
ev.preventDefault();
}, false);
Create a generic handler. In ProcessRequest event, put this base code
public void ProcessRequest(HttpContext context)
{
HttpPostedFile doc = context.Request.Files[0];
//Your code....
doc.SaveAs("YOUR_PATH" + "/" + doc.FileName);
}
The ajax post should go to this resource...
My code can work.But only refresh a page of one window.
If I open window1 and window2 , both open websocket connect.
I keyin word "test123" in window1, click sendbutton.
Only refresh window1.
How to refresh window1 and window2 ?
Client
<script>
window.onload = function() {
document.getElementById('sendbutton').addEventListener('click', sendMessage,false);
document.getElementById('connectbutton').addEventListener('click', connect, false);
}
function writeStatus(message) {
var html = document.createElement("div");
html.setAttribute('class', 'message');
html.innerHTML = message;
document.getElementById("status").appendChild(html);
}
function connect() {
ws = new WebSocket("ws://localhost:9000/ws?name=test");
ws.onopen = function(evt) {
writeStatus("connected");
}
ws.onmessage = function(evt) {
writeStatus("response: " + evt.data);
}
}
function sendMessage() {
ws.send(document.getElementById('messagefield').value);
}
</script>
</head>
<body>
<button id="connectbutton">Connect</button>
<input type="text" id="messagefield"/>
<button id="sendbutton">Send</button>
<div id="status"></div>
</body>
Play Framework WebSocketController
public class WebSocket extends WebSocketController {
public static void test(String name) {
while(inbound.isOpen()) {
WebSocketEvent evt = await(inbound.nextEvent());
if(evt instanceof WebSocketFrame) {
WebSocketFrame frame = (WebSocketFrame)evt;
System.out.println("received: " + frame.getTextData());
if(!frame.isBinary()) {
if(frame.getTextData().equals("quit")) {
outbound.send("Bye!");
disconnect();
} else {
outbound.send("Echo: %s", frame.getTextData());
}
}
}
}
}
}
You have the basic of making work a single socket. However, each socket you are creating uses your socket events. Since each of the sockets would equal a thread, you need to send the event for each socket you can have. This is why when a new socket is open you need to map it in an array of sockets.
This thread can help you out.
Websocket send data all client in playframework 2
And refer to this exemple of play with framework.
https://github.com/playframework/playframework/blob/master/samples/java/websocket-chat/app/models/ChatRoom.java#L89
Hello friends i am trying to implement the app-backend registration of app with notification hub.for implementing it i am following this notify user with notification hub but i wanted to do registration for windows phone so i have tried to do it and write this code in mobile service Api
exports.post = function(request, response) {
// Use "request.service" to access features of your mobile service, e.g.:
// var tables = request.service.tables;
// var push = request.service.push;
var azure = require('azure');
var hub = azure.createNotificationHubService('samplenotificationhub',
'full access key');
var platform = request.body.platform;
var installationId = request.header('X-ZUMO-INSTALLATION-ID');
var registrationComplete = function(error, registration) {
if (!error) {
// Return the registration.
response.send(200, registration);
} else {
response.send(500, 'Registration failed!');
}
}
// Function called to log errors.
var logErrors = function(error) {
if (error) {
console.error(error)
}
}
hub.listRegistrationsByTag(installationId, function(error, existingRegs) {
var firstRegistration = true;
if (existingRegs.length > 0) {
for (var i = 0; i < existingRegs.length; i++) {
if (firstRegistration) {
// Update an existing registration.
if (platform === 'wp') {
existingRegs[i].ChannelUri = request.body.channelUri;
hub.updateRegistration(existingRegs[i], registrationComplete);
} else {
response.send(500, 'Unknown client.');
}
firstRegistration = false;
} else {
// We shouldn't have any extra registrations; delete if we do.
hub.deleteRegistration(existingRegs[i].RegistrationId, logErrors);
}
}
} else {
// Create a new registration.
if (platform === 'wp') {
hub.mpns.createNativeRegistration(request.body.channelUri,
[request.body.CurrentDate], registrationComplete);
}
else {
response.send(500, 'Unknown client.');
}
}
});
};
i am able to get the api call from this code in my app..
private async Task AcquirePushChannel()
{
CurrentChannel = HttpNotificationChannel.Find("mychannel");
string message;
if (CurrentChannel == null)
{
CurrentChannel = new HttpNotificationChannel("mychannel");
CurrentChannel.Open();
CurrentChannel.BindToShellTile();
CurrentChannel.BindToShellToast();
}
var body = new NotificationRequest
{
channelUri = CurrentChannel.ChannelUri.ToString(),
platform = "wp",
CurrentDate = "1",
};
try
{
// Call the custom API POST method with the supplied body.
var result = await App.MobileService
.InvokeApiAsync<NotificationRequest,
RegistrationResult>("registrationapi", body,
System.Net.Http.HttpMethod.Post, null);
// Set the response, which is the ID of the registration.
message = string.Format("Registration ID: {0}", result.RegistrationId);
registrationid = result.RegistrationId;
}
catch (MobileServiceInvalidOperationException ex)
{
message = ex.Message;
}
i have seen an active api call on mobile service dashboard but not able to get response from API..
i have written this code in my table scripts so that i can send push notification to my phone it..also take a look if anything is wrong in it.
function insert(item, user, request) {
var azure = require('azure');
var hub = azure.createNotificationHubService('samplenotificationhub',
'listen signature string');
// Create the payload for a Windows Store app.
var wnsPayload = '<toast><visual><binding template="ToastText02"><text id="1">New item added:</text><text id="2">' + "tanuj" + '</text></binding></visual></toast>';
var Toasttemplate = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<wp:Notification xmlns:wp=\"WPNotification\">" +"<wp:Toast>" +"<wp:Text1>$(" + "1" + ")</wp:Text1>" +"</wp:Toast> " +"</wp:Notification>";
// Execute the request and send notifications.
request.execute({
success: function() {
// Write the default response and send a notification
// to the user on all devices by using the userId tag.
request.respond();
hub.wpns.send("1", Toasttemplate, 'wpns/toast', function(error) {
if (error) {
console.log(error);
}
});
}
});
i know this is lot of code i am putting this because the link is not mentioned for wp so just wanted to make sure i am doing right.
also please let me know first what is INSTALATIONID in var installationId = request.header('X-ZUMO-INSTALLATION-ID'); hope to get some response. any help ,idea or suggestion is appreciated.
In my other question I found out that there is no whitelist for windows phones.
Now I am looking for a native code workaround but I have never written a line of native code for windows phones. So it's not easy for me. I think I can download a page like this:
void GetAirportData()
{
var url = new Uri("http://server.example.com/data.php", UriKind.Absolute);
var webClient = new WebClient();
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(url, url);
}
But how can a get this data to my javascript app?
Here is a workaround. The following code is a Phonegap command that implements Cross Domain Call functionality.
using System;
using System.IO;
using System.Net;
using System.Runtime.Serialization;
using WP7CordovaClassLib.Cordova;
using WP7CordovaClassLib.Cordova.Commands;
using WP7CordovaClassLib.Cordova.JSON;
namespace Cordova.Extension.Commands //namespace is predefined, don't change it!
{
public class Cdc : BaseCommand //Cross domain call
{
[DataContract]
public class CdcOptions
{
[DataMember(Name = "path")]
public string Path { get; set; }
}
public void Call(string args)
{
CdcOptions options = JsonHelper.Deserialize<CdcOptions>(args);
var url = new Uri(options.Path, UriKind.Absolute);
var webClient = new WebClient();
webClient.OpenReadCompleted += (s, e) =>
{
if (e.Error != null)
{
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error"));
return;
}
//Stream -> string
var sr = new StreamReader(e.Result);
var result = sr.ReadToEnd();
DispatchCommandResult(
new PluginResult(PluginResult.Status.OK, result));
};
webClient.OpenReadAsync(url, url);
}
}
}
Test on the client side:
<script type="text/javascript">
function cdc(path, success, fail) {
PhoneGap.exec(
success, //success
fail, //fail
"Cdc", //service
"Call", //action
path //args
);
};
function onDeviceReady(e) {
cdc(
{
path: "http://stackoverflow.com/questions/9291809/workaround-for-missing-whitelist-in-phonegap-for-windows-phone"
},
function (arg) {
document.getElementById('test').innerHTML = arg;
}, function (arg) {
document.getElementById('test').innerHTML = arg;
});
}
document.addEventListener("deviceready", onDeviceReady, false);
</script>
</head>
<body>
<div id="test"></div>
</body>
</html>
Hi I can see this has been discussed but after perusing the issues/answers I still don't seem to be able to get even this simple AJAX call to bump out of ready state 1.
Here's the Javascript I have:
<script language="javascript" type="text/javascript">
var request;
function createRequest()
{
try
{
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
}
function loadClassesBySchool()
{
//get require web form pieces for this call
createRequest(); // function to get xmlhttp object
var schoolId = getDDLSelectionValue("ddlSchools");
var grade = getDDLSelectionValue("ddlGrades");
var url = "courses.php?grades=" + escape(grade) + "&schoolId=" + escape(schoolId);
//open server connection
request.open("GET", url, true);
//Setup callback function for server response
//+++read on overflow that some fixed the issue with an onload event this simply had
//+++the handle spitback 2 readystate = 1 alerts
request.onload = updateCourses();
request.onreadystatechanged = updateCourses();
//send the result
request.send();
}
function updateCourses()
{
alert('ready state changed' + request.readyState);
}
function getDDLSelectionValue(ddlID)
{
return document.getElementById(ddlID).options[document.getElementById(ddlID).selectedIndex].value;
}
</script>
The PHP is HERE just a simple print which if i navigate to in the browser (IE/Chrome) loads fine:
<?php
print "test";
?>
I'm quite new at this but seems like I can't get the most bare bones AJAX calls to work, any help as to how work past this would be greatly appreciated.
All I get out of my callback function 'updateCourses' is a 1...
Well after more digging I actually gave up and switched over to jQuery which should for all intents and purposes be doing the EXACT same thing except for the fact that jQuery works... I was just less comfortable with it but so be it.
Here's the jQuery to accomplish the same:
function loadCoursesBySchool(){
var grades = getDDLSelectionValue("ddlGrades");
var schoolId = getDDLSelectionValue("ddlSchools");
jQuery.ajax({
url: "courses.php?grades=" + grades + "&schoolId=" + schoolId,
success: function (data) {
courseDisplay(data);
}
});
}
function courseDisplay(response)
{
//check if anything was setn back!?
if(!response)
{
$("#ddlCourses").html("");
//do nothing?
}
else
{
//empty DLL
$("#ddlCourses").html("");
//add entries
$(response).appendTo("#ddlCourses");
}
}