I'm trying to get the webview control into editable mode (for UWP). Here's my code where I am injecting the js to do that:
private const string EditableParameter = "~editable~";
private const string SetBodyEditableScript = #"
try
{
document.body.contentEditable = '" + EditableParameter + #"';
}
catch(e)
{
}";
public MainPage()
{
this.InitializeComponent();
MakeWebviewEditable();
}
private const string EventNotificationFormat = #"window.external.notify('{0}');";
private async void MakeWebviewEditable()
{
await InjectJavaScriptAsync(SetBodyEditableScript.Replace(EditableParameter, "true"));
}
private async Task InjectJavaScriptAsync(string jscript)
{
await WebView.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
try
{
string result = await WebView.InvokeScriptAsync("eval", new string[] { jscript });
}
catch (Exception ex)
{
}
});
}
But it doesn't work and the webview control is still not editable.
It turned out to be pretty simple. Just had to set the designmode to true:
document.designMode='on';
Related
Im programming in Visual Code C#, i'm making a chat application in SignalR, i want to store messages in a database in MongoDB. I need a help, that how can I use the 'message' and the 'user' variable from chat.js file in the Pogram.cs?
chat.js
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
//Disable send button until connection is established
document.getElementById("sendButton").disabled = true;
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var encodedMsg = user + ": " + msg;
var li = document.createElement("li");
li.textContent = encodedMsg;
document.getElementById("messagesList").appendChild(li);
});
connection.start().then(function () {
document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
document.getElementById("sendButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
Program.cs
namespace bcwebchat
{
public class Message{
public DateTime Sent;
public string Msg;
}
public class Program
{
public static void Main(string[] args)
{
var client = new MongoClient("mongodb://localhost:27017");
var db = client.GetDatabase("DemoInsert");
var collec = db.GetCollection<Message>("DemoInsert");
collec.InsertOne(new Message
{
Sent = DateTime.Now,
Msg = "blaaahahaah"
});
I want to use the user and the message in here:
collec.InsertOne(new Message
{
Sent = DateTime.Now,
Msg = "blaaahahaah"
});
Just following this section Microsoft SignalR
First, you should create a ASP.NET Web Application
Then, create a ChatHub and insert message, it should work
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
// insert your message to database
collec.InsertOne(new Message
{
Sent = DateTime.Now,
Msg = message
});
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//some code here
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>("/chatHub");
});
}
I am able to connect to my Hub and I've hooked up OnConnected and OnDisconnected. They should add/subtract from a integer and call a client callback with the new value.
My angular application is connecting to the server successfully but my registered callback function is not being triggered.
Here is my Serverhub:
[HubName("online")]
public class OnlineHub : Hub
{
private static int userCount = 0;
public override Task OnConnected()
{
userCount++;
Clients.All.listUpdated(userCount);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
userCount--;
Clients.All.listUpdated(userCount);
return base.OnDisconnected(stopCalled);
}
}
And here's my Angular SignalRService:
import { AppSettings } from './../app.settings';
import { EventEmitter, Injectable, OnDestroy } from '#angular/core';
declare const $: any;
#Injectable()
export class SignalRService {
// Declare the variables
private onlineHub: any;
// create the Event Emitter
public messageReceived: EventEmitter<any>;
public connectionEstablished: EventEmitter<Boolean>;
public connectionExists: Boolean;
constructor(private appSettings: AppSettings) {
// Setup
this.connectionEstablished = new EventEmitter<Boolean>();
this.messageReceived = new EventEmitter<any>();
this.connectionExists = false;
}
// This method gets executed from angular controller
public initialize(proxyName: string): void {
this.onlineHub = $.connection.online;
this.onlineHub.client.listUpdated = function(list: any): void {
console.log(list);
this.messageReceived.emit(list);
};
this.startConnection();
}
private startConnection(): void {
$.connection.hub.url = this.appSettings.SIGNALR_BASE_URL + '/signalr';
$.connection.hub.start()
.done((data: any) => {
console.log('SignalR Connected with: ' + data.transport.name);
this.connectionEstablished.emit(true);
this.connectionExists = true;
})
.fail((error: any) => {
console.log('SignalR could not connect: ' + error);
this.connectionEstablished.emit(false);
});
}
private registerOnServerEvents() {
this.onlineHub.client.listUpdated = function(list: any): void {
console.log(list);
this.messageReceived.emit(list);
};
}
}
I am registering my callback "listUpdated" before I run start() as the documentation says and $.connection.hub contains client.listUpdated before start() is called so it should register. But still, the OnConnected method is not called.
I fixed this issue by surrounding the OnConnected() and OnDisconnected() code in try/catch block and created a clientside method called "error" that returns eventual exceptions to the client. That way I found out that I had a Json Serialization issue.
My Hub now looks like this:
[HubName("online")]
public class OnlineHub : Hub
{
private static int userCount = 0;
public override Task OnConnected()
{
try
{
userCount++;
Clients.All.listUpdated(userCount);
}
catch (Exception exc)
{
Clients.All.error(exc);
}
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
try
{
userCount--;
Clients.All.listUpdated(userCount);
}
catch (Exception exc)
{
Clients.All.error(exc);
}
return base.OnDisconnected(stopCalled);
}
}
And I register the error callback on the js client BEFORE calling start():
this.onlineHub.client.error = (exc: any): void => {
console.log('Error occured:', exc);
};
right now i am throwing error if "dateofBirth" is not found that just sent empty object back to client , how can i pass error object back to client instead of empty object. basically want to send back to process catch
main.ts
export class GetSpecialtyQuestionsController extends Controller {
public static async process(#Request() request: ExpressRequest,
response: ExpressResponse): Promise < any > {
try {
const instance = new GetSpecialtyQuestionsController();
const data = await instance.execute(request);
response.status(200);
response.send(data);
} catch (err) {
response.status(200);
response.send(err.message);
}
}
// private _request: IRequestURL[] = [];
constructor() {
super();
}
private async execute(#Request() request: ExpressRequest): Promise < any > {
// const specialtyMembers = this.getSpecialtyMemberInfoFakeObject();
const specialtyMembers = await new SpecialtyCacheUtility().getSpecialtyMemberInfoCache(
request.body.getSpecialtyQuestionsRequest.header.serviceContext.tokenID);
if (!specialtyMembers) {
return this.errorHandler(request);
}
let proxyMember: ISpecialtyInfoObj = {}
as ISpecialtyInfoObj;
for (const member of specialtyMembers) {
if (member.specialtyIdEnc === request.body.getSpecialtyQuestionsRequest.details.specialtyIdEnc) {
proxyMember = member;
if (!member.dateOfBirth) {
throw new Error('no patient info for given HBS ID');
}
break;
}
}
}
Create your custom exception object to pass data while throw error
class CustomError extends Error {
constructor(foo = 'bar', ...params) {
// Pass remaining arguments (including vendor specific ones) to parent constructor
super(...params);
// Maintains proper stack trace for where our error was thrown (only available on V8)
if (Error.captureStackTrace) {
Error.captureStackTrace(this, CustomError);
}
// Custom debugging information
this.foo = foo;
this.date = new Date();
}
}
try {
throw new CustomError('baz', 'bazMessage');
} catch(e){
console.log(e.foo); //baz
console.log(e.message); //bazMessage
console.log(e.stack); //stacktrace
}
For reference read more from official mdn documentation - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
using Discord.Commands;
using Discord;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using NadekoBot.Services;
using System.Threading;
using System.Collections.Generic;
using NadekoBot.Services.Database.Models;
using System.Net.Http;
using NadekoBot.Attributes;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NLog;
using NadekoBot.Extensions;
using System.Diagnostics;
namespace NadekoBot.Modules.Searches
{
public partial class Searches
{
public class StreamStatus
{
public bool IsLive { get; set; }
public string ApiLink { get; set; }
public string Views { get; set; }
public string Game { get; set; }
public string Status { get; set;}
}
public class HitboxResponse {
public bool Success { get; set; } = true;
[JsonProperty("media_is_live")]
public string MediaIsLive { get; set; }
public bool IsLive => MediaIsLive == "1";
[JsonProperty("media_views")]
public string Views { get; set; }
}
public class TwitchResponse
{
public string Error { get; set; } = null;
public bool IsLive => Stream != null;
public StreamInfo Stream { get; set; }
public class StreamInfo
{
public int Viewers { get; set; }
public string Game { get; set; }
public ChannelInfo Channel { get; set;}
public class ChannelInfo {
public string Status { get; set; )
}
}
}
public class BeamResponse
{
public string Error { get; set; } = null;
[JsonProperty("online")]
public bool IsLive { get; set; }
public int ViewersCurrent { get; set; }
}
public class StreamNotFoundException : Exception
{
public StreamNotFoundException(string message) : base("Stream '" + message + "' not found.")
{
}
}
[Group]
public class StreamNotificationCommands : ModuleBase
{
private static Timer checkTimer { get; }
private static ConcurrentDictionary<string, StreamStatus> oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static ConcurrentDictionary<string, StreamStatus> cachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private static Logger _log { get; }
private static bool FirstPass { get; set; } = true;
static StreamNotificationCommands()
{
_log = LogManager.GetCurrentClassLogger();
checkTimer = new Timer(async (state) =>
{
oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(cachedStatuses);
cachedStatuses.Clear();
IEnumerable<FollowedStream> streams;
using (var uow = DbHandler.UnitOfWork())
{
streams = uow.GuildConfigs.GetAllFollowedStreams();
}
await Task.WhenAll(streams.Select(async fs =>
{
try
{
var newStatus = await GetStreamStatus(fs).ConfigureAwait(false);
if (FirstPass)
{
return;
}
StreamStatus oldStatus;
if (oldCachedStatuses.TryGetValue(newStatus.ApiLink, out oldStatus) &&
(oldStatus.IsLive != newStatus.IsLive)
{
var server = NadekoBot.Client.GetGuild(fs.GuildId);
if (server == null)
return;
var channel = server.GetTextChannel(fs.ChannelId);
if (channel == null)
return;
try
{
var msg = await channel.EmbedAsync(fs.GetEmbed(newStatus)).ConfigureAwait(false);
}
catch { }
}
}
catch { }
}));
FirstPass = false;
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
}
private static async Task<StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true)
{
string response;
StreamStatus result;
switch (stream.Type)
{
case FollowedStream.FollowedStreamType.Hitbox:
var hitboxUrl = $"https://api.hitbox.tv/media/status/{stream.Username.ToLowerInvariant()}";
if (checkCache && cachedStatuses.TryGetValue(hitboxUrl, out result))
return result;
using (var http = new HttpClient())
{
response = await http.GetStringAsync(hitboxUrl).ConfigureAwait(false);
}
var hbData = JsonConvert.DeserializeObject<HitboxResponse>(response);
if (!hbData.Success)
throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]");
result = new StreamStatus()
{
IsLive = hbData.IsLive,
ApiLink = hitboxUrl,
Views = hbData.Views
};
cachedStatuses.AddOrUpdate(hitboxUrl, result, (key, old) => result);
return result;
case FollowedStream.FollowedStreamType.Twitch:
var twitchUrl = $"https://api.twitch.tv/kraken/streams/{Uri.EscapeUriString(stream.Username.ToLowerInvariant())}?client_id=67w6z9i09xv2uoojdm9l0wsyph4hxo6";
if (checkCache && cachedStatuses.TryGetValue(twitchUrl, out result))
return result;
using (var http = new HttpClient())
{
response = await http.GetStringAsync(twitchUrl).ConfigureAwait(false);
}
var twData = JsonConvert.DeserializeObject<TwitchResponse>(response);
if (twData.Error != null)
{
throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]");
}
result = new StreamStatus()
{
IsLive = twData.IsLive,
ApiLink = twitchUrl,
Views = twData.Stream?.Viewers.ToString() ?? "0"
Game = twData.Stream?.Game,
Status = twData.Stream?.Channel?.Status
};
cachedStatuses.AddOrUpdate(twitchUrl, result, (key, old) => result);
return result;
case FollowedStream.FollowedStreamType.Beam:
var beamUrl = $"https://beam.pro/api/v1/channels/{stream.Username.ToLowerInvariant()}";
if (checkCache && cachedStatuses.TryGetValue(beamUrl, out result))
return result;
using (var http = new HttpClient())
{
response = await http.GetStringAsync(beamUrl).ConfigureAwait(false);
}
var bmData = JsonConvert.DeserializeObject<BeamResponse>(response);
if (bmData.Error != null)
throw new StreamNotFoundException($"{stream.Username} [{stream.Type}]");
result = new StreamStatus()
{
IsLive = bmData.IsLive,
ApiLink = beamUrl,
Views = bmData.ViewersCurrent.ToString()
};
cachedStatuses.AddOrUpdate(beamUrl, result, (key, old) => result);
return result;
default:
break;
}
return null;
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task Hitbox([Remainder] string username) =>
await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Hitbox)
.ConfigureAwait(false);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task Twitch([Remainder] string username) =>
await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Twitch)
.ConfigureAwait(false);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task Beam([Remainder] string username) =>
await TrackStream((ITextChannel)Context.Channel, username, FollowedStream.FollowedStreamType.Beam)
.ConfigureAwait(false);
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task ListStreams()
{
IEnumerable<FollowedStream> streams;
using (var uow = DbHandler.UnitOfWork())
{
streams = uow.GuildConfigs
.For(Context.Guild.Id,
set => set.Include(gc => gc.FollowedStreams))
.FollowedStreams;
}
if (!streams.Any())
{
await Context.Channel.SendConfirmAsync("You are not following any streams on this server.").ConfigureAwait(false);
return;
}
var text = string.Join("\n", await Task.WhenAll(streams.Select(async snc =>
{
var ch = await Context.Guild.GetTextChannelAsync(snc.ChannelId);
return $"`{snc.Username}`'s stream on **{(ch)?.Name}** channel. 【`{snc.Type.ToString()}`】";
})));
await Context.Channel.SendConfirmAsync($"You are following **{streams.Count()}** streams on this server.\n\n" + text).ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)]
public async Task RemoveStream(FollowedStream.FollowedStreamType type, [Remainder] string username)
{
username = username.ToLowerInvariant().Trim();
var fs = new FollowedStream()
{
ChannelId = Context.Channel.Id,
Username = username,
Type = type
};
bool removed;
using (var uow = DbHandler.UnitOfWork())
{
var config = uow.GuildConfigs.For(Context.Guild.Id, set => set.Include(gc => gc.FollowedStreams));
removed = config.FollowedStreams.Remove(fs);
if (removed)
await uow.CompleteAsync().ConfigureAwait(false);
}
if (!removed)
{
await Context.Channel.SendErrorAsync("No such stream.").ConfigureAwait(false);
return;
}
await Context.Channel.SendConfirmAsync($"Removed `{username}`'s stream ({type}) from notifications.").ConfigureAwait(false);
}
[NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)]
public async Task CheckStream(FollowedStream.FollowedStreamType platform, [Remainder] string username)
{
var stream = username?.Trim();
if (string.IsNullOrWhiteSpace(stream))
return;
try
{
var streamStatus = (await GetStreamStatus(new FollowedStream
{
Username = stream,
Type = platform,
}));
if (streamStatus.IsLive)
{
await Context.Channel.SendConfirmAsync($"Streamer {username} is online with {streamStatus.Views} viewers.");
}
else
{
await Context.Channel.SendConfirmAsync($"Streamer {username} is offline.");
}
}
catch
{
await Context.Channel.SendErrorAsync("No channel found.");
}
}
private static async Task TrackStream(ITextChannel channel, string username, FollowedStream.FollowedStreamType type)
{
username = username.ToLowerInvariant().Trim();
var fs = new FollowedStream
{
GuildId = channel.Guild.Id,
ChannelId = channel.Id,
Username = username,
Type = type,
};
StreamStatus status;
try
{
status = await GetStreamStatus(fs).ConfigureAwait(false);
}
catch
{
await channel.SendErrorAsync("Stream probably doesn't exist.").ConfigureAwait(false);
return;
}
using (var uow = DbHandler.UnitOfWork())
{
uow.GuildConfigs.For(channel.Guild.Id, set => set.Include(gc => gc.FollowedStreams))
.FollowedStreams
.Add(fs);
await uow.CompleteAsync().ConfigureAwait(false);
}
await channel.EmbedAsync(fs.GetEmbed(status), $"🆗 I will notify this channel when status changes.").ConfigureAwait(false);
}
}
}
public static class FollowedStreamExtensions
{
public static EmbedBuilder GetEmbed(this FollowedStream fs, Searches.StreamStatus status)
{
var embed = new EmbedBuilder().WithTitle(fs.Username)
.WithUrl(fs.GetLink())
.WithThumbnailUrl(fs.GetLink())
.WithDescription(status.Status)
.AddField(efb => efb.WithName("Status")
.WithValue(status.IsLive ? "Online" : "Offline")
.WithIsInline(true))
.AddField(efb => efb.WithName("Viewers")
.WithValue(status.IsLive ? status.Views : "-")
.WithIsInline(true))
.AddField(efb => efb.WithName("Game">
.WithValue(status.Game)
.WithIsInlin(true))
.AddField(efb => efb.WithName("Platform")
.WithValue(fs.Type.ToString())
.WithIsInline(true))
.WithColor(status.IsLive ? "NadekoBot.OkColor" : "NadekoBot.ErrorColor");
return embed;
}
public static string GetLink(this FollowedStream fs) {
if (fs.Type == FollowedStream.FollowedStreamType.Hitbox)
return $"http://www.hitbox.tv/{fs.Username}/";
else if (fs.Type == FollowedStream.FollowedStreamType.Twitch)
return $"http://www.twitch.tv/{fs.Username}/";
else if (fs.Type == FollowedStream.FollowedStreamType.Beam)
return $"https://beam.pro/{fs.Username}/";
else
return "??";
}
}
}
I'm attempting to get this discord bot to announce when someone streaming on Twitch goes Live by amending its code to give me more information (ie Game and Status) but I keep getting an error that I can't for the life of me find and fix! I was told the issue is between coding on a PC and coding on a Mac? Not sure that's 100% accurate. Can someone please run this code and help me get this to work properly? Thanks!
I'm trying to learn websocket. I started sending simple string between peers and everything was fine. Now I'm trying to send Object to my javascript client but the onmessage function never fires. Here is the code:
Java serverside:
#ServerEndpoint(value = "/event/{id}",
encoders={PositionJSONEncoder.class},
decoders={PositionJSONDecoder.class}
)
public class SocketManager {
private static ConcurrentHashMap<String, Session> users = new ConcurrentHashMap<String, Session>();
#OnMessage
public void onMessage(Position position, #PathParam("id") String id, Session session) {
log.info("user "+id+", "+position.toString());
try {
for(Entry<String, Session> entry : users.entrySet()) {
if(!entry.getKey().equals(position.getUserID()) && entry.getValue().isOpen()) {
entry.getValue().getBasicRemote().sendObject(position);
}
}
} catch (EncodeException ee) {
log.error(ee);
} catch (IOException ioe) {
log.error(ioe);
}
}
}
The serverendpoint encoder (I'll omit the decoder, server handle data correctly):
public class PositionJSONEncoder implements Encoder.Text<Position>{
private Gson gson = new Gson();
public void destroy() {}
public void init(EndpointConfig arg0) {}
public String encode(Position arg0) throws EncodeException {
return gson.toJson(arg0);
}
}
The relevant client side (AngularJS):
app.factory('socket', function() {
var service = {};
service.ws = {};
service.connect = function(userID) {
this.ws = new WebSocket("ws://localhost:8080/event/"+userID);
};
service.disconnect = function() {
if(this.ws != undefined && this.ws != null) {
this.ws.onclose();
}
};
service.ws.onopen = function() {
// TODO
};
service.ws.onmessage = function(msg) {
try {
alert('roba: '+JSON.parse(msg.data));
} catch(err) {
alert(err.message);
}
};
service.ws.onclose = function() {
// TODO
};
service.ws.onerror = function(evt) {
alert(evt.data);
};
return service;
});
The model the server send:
public class Position {
private String userID;
private Float lat;
private Float lng;
public Position() {}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public Float getLat() {
return lat;
}
public void setLat(Float lat) {
this.lat = lat;
}
public Float getLng() {
return lng;
}
public void setLng(Float lng) {
this.lng = lng;
}
#Override
public String toString() {
return userID+"["+"lat: "+lat+", "+"lng: "+lng+"]";
}
}
My pom's dependencies:
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- GSON JSON serializer -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.7.1</version>
</dependency>
</dependencies>
The server gets the JSON object from the client correctly, but when it sends some Position object back the client, the onmessage function won't fire. I can see the Encoder is working as it returns strings like this:
{"userID":"bob","lat":2.0,"lng":2.0}
I see the websocket carry the messages:
but my javascript onmessage function always stay silent. I also implemented an onerror function but I can't get any feedback from it too. I'm using wildfly-8.0.0.Final.
Update: I implement a java websocket client. This client receive websocket frame sent by the server. Is my AngularJS client wrong?
I found what was wrong. In my javascript client I assigned a function to an undefined object. Here:
service.ws.onmessage = function(msg) {
try {
alert('roba: '+JSON.parse(msg.data));
} catch(err) {
alert(err.message);
}
};
service.ws.onmessage was undefined, that's why onmessage function never fire. I change my angular factory in this way:
app.factory('socket', function() {
var service = {};
service.ws = {};
service.connect = function(userID) {
this.ws = new WebSocket("ws://localhost:8080/event/"+userID);
this.ws.onmessage = function(msg) {
try {
alert('roba: '+JSON.parse(msg.data).lat+' :: '+JSON.parse(msg.data).lng);
} catch(err) {
alert(err.message);
}
};
this.ws.onerror = function(evt) {
alert('error: '+evt.data);
};
};
service.disconnect = function() {
if(this.ws != undefined && this.ws != null) {
this.ws.onclose();
}
};
return service;
});