I have 4 textboxes that are filling in same time after user push send button Using SignalR. In one part I am sending textbox values to all users and this is working. But when I try to send the values to specific user, after pushing the button, all textboxes get empty.
This is the code that is working, sending values to all users:
This is Hub:
public void Send(string loanType, string loanAmount, string interestRates, string payment)
{
User sender = GetUser(Context.User.Identity.Name);
var username = sender.Name;
IEnumerable<string> connectionIds = sender.ConnectionIds;
//All connected clients.
Clients.All.broadcastMessage(loanType, loanAmount, interestRates, payment);
}
and this is js:
$('#sendmessage').click(function (e) {
sendPayment();
e.preventDefault();
});
function sendPayment() {
var msgValue = $msgTxt.val();
var loanType = $('#txtLoanType').val();
var loanAmount = $('#txtLoanAmount').val();
var interestRates = $('#txtInterestRates').val();
var payment = $('#txtPayment').val();
if (loanType !== null && loanType.length > 0 && loanAmount !== null && loanAmount.length > 0 && interestRates !== null && interestRates.length > 0
&& payment !== null && payment.length > 0) {
if (viewModel.isInPrivateChat()) {
$.connection.hub.start();
chatHub.server.send(msgValue, viewModel.privateChatUser(), $('#txtLoanType option:selected').val(), $('#txtLoanAmount').val(), $('#txtInterestRates').val(), $('#txtPayment').val());
}
else {
// Call the Send method on the hub.
chatHub.server.send($('#txtLoanType option:selected').val(), $('#txtLoanAmount').val(), $('#txtInterestRates').val(), $('#txtPayment').val());
}
}
chatHub.client.broadcastMessage = function (loanType, loanAmount, interestRates, payment) {
$('#txtLoanType').val(loanType);
$('#txtLoanAmount').val(loanAmount);
$('#txtInterestRates').val(interestRates);
$('#txtPayment').val(payment);
};
but when I try to send values to specific user it is not working: as I am debussing the C# code is working I thing the problem is in JS:
this is C# method that send values of text boxes to specific user:
public void Send(string message, string to, string loanType, string loanAmount, string interestRates, string payment)
{
User receiver;
if (Users.TryGetValue(to, out receiver))
{
User sender = GetUser(Context.User.Identity.Name);
IEnumerable<string> allReceivers;
lock (receiver.ConnectionIds)
{
lock (sender.ConnectionIds)
{
allReceivers = receiver.ConnectionIds.Concat(sender.ConnectionIds);
}
}
foreach (var cid in allReceivers)
{
Clients.Client(cid).broadcastMessage(new { message = message, isPrivate = true, loanType = loanType,
loanAmount = loanAmount,
interestRates = interestRates,
payment = payment
});
}
}
}
it will call the Private part in JS file that is :
if (viewModel.isInPrivateChat()) {
$.connection.hub.start();
chatHub.server.send(msgValue, viewModel.privateChatUser(), $('#txtLoanType option:selected').val(), $('#txtLoanAmount').val(), $('#txtInterestRates').val(), $('#txtPayment').val());
The function signatures do not match. There are different number of paramerters, they have to match exactly or the javascript function will never be called, it looks like you are trying use the parameters for the send function, when you are calling the broadcastMessage function.
In the JavaScript for the user you are looking for:
function (loanType, loanAmount, interestRates, payment)
But you are sending:
broadcastMessage(new { message = message, isPrivate = true, loanType = loanType,
loanAmount = loanAmount,
interestRates = interestRates,
payment = payment
})
Related
I am working on a very simple project where a user sends a private message to another through the server using the SignalR library. I used this code as a base https://www.codeproject.com/Articles/562023/Asp-Net-SignalR-Chat-Room
I started with an easy functionality test but my recipient is not receiving the message and It doesn't work properly, can you help me understand why?
In my program usernames are generated dynamically in the session, those in the code below are not real data, I just used them for the example
Client side
</script>
<script type="text/javascript" src="/Scripts/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="/Scripts/jquery.signalR-1.2.2.js"></script>
<script type="text/javascript" src="/signalr/hubs"></script>
<script type="text/javascript">
$(function () {
var chatHub = $.connection.chatHub;
console.log('connected')
chatHub.client.messageReceived = function (userName, message) {
alert("You have a new message");
}
$.connection.hub.start().done(function () {
chatHub.server.connect('FromUsername');
$('#btnSend').click(function () {
var userId='ToUsername'
var msg = 'Test';
chatHub.server.sendPrivateMessage(userId, msg);
});
});
});
</script>
Server side
public class ChatHub : Hub
{
#region Data Members
static List<UserDetail> ConnectedUsers = new List<UserDetail>();
static List<MessageDetail> CurrentMessage = new List<MessageDetail>();
#endregion
#region Methods
public void Connect(string userName)
{
var id = Context.ConnectionId;
if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0)
{
ConnectedUsers.Add(new UserDetail { ConnectionId = id, UserName = userName });
// send to caller
Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage);
// send to all except caller client
Clients.AllExcept(id).onNewUserConnected(id, userName);
}
}
public void SendMessageToAll(string userName, string message)
{
// store last 100 messages in cache
AddMessageinCache(userName, message);
// Broad cast message
Clients.All.messageReceived(userName, message);
}
public void SendPrivateMessage(string toUserId, string message)
{
string fromUserId = Context.ConnectionId;
var toUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == toUserId) ;
var fromUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == fromUserId);
if (toUser != null && fromUser!=null)
{
// send to
Clients.Client(toUserId).sendPrivateMessage(fromUserId, fromUser.UserName, message);
// send to caller user
Clients.Caller.sendPrivateMessage(toUserId, fromUser.UserName, message);
}
}
public override System.Threading.Tasks.Task OnDisconnected()
{
var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
if (item != null)
{
ConnectedUsers.Remove(item);
var id = Context.ConnectionId;
Clients.All.onUserDisconnected(id, item.UserName);
}
return base.OnDisconnected();
}
#endregion
#region private Messages
private void AddMessageinCache(string userName, string message)
{
CurrentMessage.Add(new MessageDetail { UserName = userName, Message = message });
if (CurrentMessage.Count > 100)
CurrentMessage.RemoveAt(0);
}
#endregion
}
When I execute the program it shows log "connected" on the console and the event fires when button is pressed but for some reason the message is not sent or not being received
What are you missing in your code is to start to listen to your server, what that method send to you like
.on("YourMethodName")
after the connection is made. Also is recommended to resolve users with connectionId, you you can call a specific user like:
Clients.Client(Context.ConnectionId).sendPrivateMessage(fromUserId, fromUser.UserName, message);
I'm sending by ajax post request to a method in the controller a string 'userName' that I should kick.
Is it possible to remove the user from current hub calling the method in the controller?
public ActionResult Kick(string userName)
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
var user = userService.GetUserByName(userName);
var room = chatRoomService.GetRoomById(user.ChatRoomId.Value);
user.IsKicked = true;
userService.LeaveRoom(user);
hubContext.Groups.Remove(user.ConnectionIdInHub, room.Name);
return Json(new {success = true});
}
Could i somewhere in this method disconnect user from hub?
Server Side-
You should store user's connection ID at the time of his connection.
Like this in server side-
public override Task OnConnected()
{
Boolean isFoundAnydevice = false;
if(receivedClientId.Length>0) //With Param
{
int noOfSelectedDevice = _context.TargatedDevice.Where(x => x.PhoneId == receivedClientId).Count();
if (noOfSelectedDevice > 0)
isFoundAnydevice = true;
}
else //With no Param
{
String deviceId = _context.Device.Where(d => d.ConnectionId == this.Context.ConnectionId).Select(d => d.ClientId).SingleOrDefault();
int noOfSelectedDevice = _context.TargatedDevice.Where(x => x.PhoneId == deviceId).Count();
if (noOfSelectedDevice > 0)
isFoundAnydevice = true;
}
if (isFoundAnydevice)
{
_logger.LogWarning(
receivedClientId + " added to Test group"
);
Groups.Add(this.Context.ConnectionId, testGroupName);
}
return base.OnConnected();
}
Then you can easily find the user's connection ID from DB.
Now you can easily stop the hub connection like this-
public Task Disconnect(string connectionId)
{
try
{
lock (_lock)
{
var connections = _registeredClients.Where(c => c.Value.Any(connection => connection == connectionId)).FirstOrDefault();
// if we are tracking a client with this connection
// remove it
if (!CollectionUtil.IsNullOrEmpty(connections.Value))
{
connections.Value.Remove(connectionId);
// if there are no connections for the client, remove the client from the tracking dictionary
if (CollectionUtil.IsNullOrEmpty(connections.Value))
{
_registeredClients.Remove(connections.Key);
}
}
}
}
catch (Exception ex)
{
Log.Error(this, "Error on disconnect in hub", ex);
}
return null;
}
More can be found in here.
Client Side-
If you like to do it from client side, you can do this-
$.connection.hub.stop();
Hope you have your answer
This question already has an answer here:
Auto-generation of email with username and random password on creation of new user
(1 answer)
Closed 6 years ago.
I need to convert this javascript file into java code.Please help
if (document.isContainer && document.displayPath == "/Company Home/User Homes") {
var owner = document.properties["cm:owner"];
var pNode = people.getPerson(owner);
if (pNode!=null && pNode.exists()){
var userName = pNode.properties.userName;
var email = pNode.properties.email;
var randPassword = Math.random().toString(36).substr(2, 30)+"-"+(Date.now());
people.setPassword(userName, randPassword);
logger.debug("Invitation mail: User "+userName+" password has been changed.");
var mail = actions.create("mail");
//mail.parameters.from = "noreply#customdomain";
mail.parameters.to = email;
mail.parameters.subject = "Welcome to the Site, login: "+userName+", password: "+randPassword;
mail.parameters.template = companyhome.childByNamePath("Data Dictionary/Email Templates/Invite Email Templates/invite_user_email.ftl");
var templateModel = new Array();
templateModel['newPassword'] = randPassword; // use ${newPassword} expression inside template
mail.parameters.template_model = templateModel;
mail.executeAsynchronously(document);
logger.debug("Invitation mail has been sent to "+email);
} else {
logger.warn("Invitation mail: User not found: "+owner);
}
} else {
logger.warn("Invitation mail: Document "+document.name+" / "+document.nodeRef+" is not a user home folder.");
}
Hope this should help you.
public void createUser()
{
final String randPassword = getRandonPassword();
final String userName= "someuser";
final String email = "someuser#example.com";
authenticationService.setAuthentication(userName, randPassword.toCharArray());
System.out.println(randPassword);
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>()
{
public Void doWork() throws Exception
{
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME,userName);
properties.put(ContentModel.PROP_PASSWORD,randPassword);
properties.put(ContentModel.PROP_EMAIL,email);
NodeRef personNodeRef = personService.createPerson(properties);
personService.notifyPerson(userName, randPassword);
return null;
}
}, AuthenticationUtil.getSystemUserName());
}
private String getRandonPassword()
{
Calendar calendar = Calendar.getInstance();
SecureRandom random = new SecureRandom();
String randomPassword = new BigInteger(130, random).toString(32);
randomPassword = randomPassword +"-" + calendar.getTimeInMillis();
return randomPassword ;
}
I'm making a simple money transaction app where user1 transfer money to user2 using parse.com and cloud code to give user1 permission using masterkey to override all other permissions.
final ParseQuery<ParseObject> parseQuery = ParseQuery.getQuery(user.getClassName());
Log.d("class found : ",String.valueOf(user.getClassName()));
parseQuery.whereMatches("AccountNumber", mAccountNumber.getText().toString().trim());
parseQuery.getFirstInBackground(new GetCallback<ParseObject>() {
#Override
public void done(final ParseObject parseObject, ParseException e) {
if (parseObject != null) {
Log.d("userID",String.valueOf(parseObject.getObjectId()));
balance = Integer.parseInt(mbalance.getText().toString());
q = parseObject.getInt("balance");
parseObject.put("balance", balance + q);
parseObject.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Toast.makeText(TransferToAccount.this, "DOne!!", Toast.LENGTH_SHORT).show();
} else {
Log.d("Exception", "1");
e.printStackTrace();
}
}
});
} else {
Log.d("Exception", "2");
Toast.makeText(TransferToAccount.this, "No user found ", Toast.LENGTH_SHORT).show();
e.printStackTrace();
and this is the could code :
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
Parse.Cloud.useMasterKey();
var user = request.user;
if (user.existed()) { return; }
user.setACL(new Parse.ACL(user));
user.save();
// add user to role
var roleName = "member";
var roleQuery = new Parse.Query(Parse.Role);
roleQuery.equalTo("name", roleName);
roleQuery.first().then(function(role) {
role.getUsers().add(user);
// save role
return role.save();
});
when I try to transfer I get an Exception :
W/System.err: com.parse.ParseException: java.lang.IllegalArgumentException: Cannot save a ParseUser that is not authenticated.
and
W/System.err: Caused by: java.lang.IllegalArgumentException: Cannot save a ParseUser that is not authenticated.
sorry if I made myself unclear.
You cant assign a role to a user before he is saved. Try to change it to afterSave trigger.
after reading this , I could solve my problem by creating a second class with a pointer to _User without the need to cloud code .
Based On : Blackberry Wiki Screen
With my full code : My Full Code
If i user onscreenready function to PASS MY PARAMETER from page A like this :
ondomready: function(element, id) {
if (id == 'UPDATE') {
UPDATE_initialLoad(element, params);
}
}
For pages that I would give / throw parameters (Let's just say page B), how do I win or get results / parameters provided by the previous form. I want to make a form update the data in the form, and will be filled all the time throwing fieldnya parameter data.
Im using like this in my Page B :
function UPDATE_initialLoad(element, params) {
setTimeout(UPDATE_loadAfterTimeout,100);
}
function UPDATE_loadAfterTimeout() {
var id = data_id
var nmDepan = data_depan
var nmBelakang = data_belakang
var phone = data_phone
var email = data_email
document.getElementById('txtID').value = id
document.getElementById('txtNMDEPAN').value = nmDepan
document.getElementById('txtNMBELAKANG').value = nmBelakang
document.getElementById('txtPhone').value = phone
document.getElementById('txtEmail').value = email
}
But result is failed...
Please help me
You'll want to push data to the page:
bb.pushScreen("myPage.html", "UPDATE", myParams);
Then this will fire when the page is loaded:
ondomready: function(element, id, params) {
if (id == 'UPDATE') {
UPDATE_initialLoad(element, params);
}
}
Make sure to pass the parameters to your delayed function:
function UPDATE_initialLoad(element, params) {
setTimeout(UPDATE_loadAfterTimeout(params),100);
}
function UPDATE_loadAfterTimeout(params) {
var id = params['data_id'];
var nmDepan = params['data_depan'];
var nmBelakang = params['data_belakang'];
var phone = params['data_phone'];
var email = params['data_email'];
document.getElementById('txtID').value = id
document.getElementById('txtNMDEPAN').value = nmDepan
document.getElementById('txtNMBELAKANG').value = nmBelakang
document.getElementById('txtPhone').value = phone
document.getElementById('txtEmail').value = email
}
I hope this helps.