How to send chat messages using converse library - javascript

I am using openfire as an XMPP server and using converse as client library. I want to send a chat message from my chat window to openfire. For this I want to send the text to a converse method which will send the message to the XMPP server.
I am trying to send the message using the following:
var msg = converse.env.$msg({
from: 'a1#localhost',
to: 'a6#localhost',
type: 'chat',
body: "Hi"
});
converse.send(msg);
But this sends the following frame in network of console in websocket:
message from='a1#localhost' to='a6#localhost' type='chat' body='Hi' xmlns='jabber:client'/>
This does not transfer message to the other user neither it stores it in the table. I am pretty much sure I am calling a wrong function. Can anyone povide any help.

You are calling the right function.
What you'll probably miss:
Listener of messages in "a6#localhost" client: as I read in documentation there are few functions
Probably, the right name of server. "localhost" has problem. You can
check Openfire for real service name on his own web panel
To check if a message it's delivered in Openfire you'll can check
OF's log (check debug one, but probably you'll have to enable it).
Real time messages are not stored on database, only groupchat's ones
and not everytime AND offline messages. To not find them on db means nothing
https://conversejs.org/docs/html/development.html
converse.chats.open('buddy#example.com');
converse.chats.get('buddy#example.com');
converse.listen.on('message', function (event, messageXML) { ... });

The syntax is wrong. conversejs uses strophe plugin to construct and send messages. It exposes the strophe $msg message builder for constructing stanzas. It has to be in the following format:
converse.env.$msg({from: 'a1#localhost', to: 'a6#localhost', type: 'chat'}).c('body').t('Hi');
You need to add a body node and within it a text node for the message.
You can also create and add your own api method and internally create a method that sends your custom stanza, and expose it using the api.

Related

RabbitMQ: Handshake Terminated by server (ACCESS-REFUSED)

I'm trying to send RabbitMQ messages from my host machine to a Minikube instance with a RabbitMQ cluster deployed.
When running my send script, I get hit with this error:
Handshake terminated by server: 403 (ACCESS-REFUSED) with message "ACCESS_REFUSED - Login was refused
using authentication mechanism PLAIN. For details see the broker logfile.
In the broker logfiles I can see this line:
Error on AMQP connection <0.13226.0> (172.17.0.1:40157 -> 172.17.0.8:5672, state: starting):
PLAIN login refused: user 'rabbitmq-cluster-default-user' - invalid credentials
I'm sure I have the correct credentials since I got them directly from the RabbitMQ pod, following the official documentation (link).
My send script is below:
const amqp = require('amqplib/callback_api');
const cluster = "amqp://rabbitmq-cluster-default-user:dJhLl2aVF78Gn07g2yGoRuwjXSc6tT11#192.168.49.2:30861";
amqp.connect(cluster, function(error0, connection)
{
if (error0)
{
throw error0;
}
connection.createChannel(function(error1, channel)
{
if (error1)
{
throw error1;
}
const queue = "files";
var msg = {
name: "Hello World"
};
var msgJson = JSON.stringify(msg);
channel.assertQueue(queue, {
durable: false
});
channel.sendToQueue(queue, Buffer.from(msgJson));
});
});
I know the code works as I ran the exact same script for my localhost setup and it worked. The only thing I've changed is the URL (for the Minikube RabbitMQ service).
I've seen a few other posts that contain a similar issue but most solutions are about including the correct credentials in the URI, which I have done.
Any other ideas?
You can use port forwarding the rabbitMQ service to your local machine and use UI login and check the password with the UI given by the RabbitMQ itself.
kubectl port-forward svc/rabbitmq UI-PORT:UI-PORT (must be 15672)
then from a browser
localhost:15762
must be enough
For clearance you can check if you can login from the container itself. If the login from the container fails you can also check the yaml file or the helm chart you are using for login methods and credentials. Plain login may be disabled.
Another situation may be with the distrubution. When deploying RabbitMQ I try to use bitnami charts. I can suggest them.
If all these fails there is another way you can use. You can try to create another user with admin privileges to connect to RabbitMQ and then keep using it.
For more information, you can post container/pod logs for us to see.
Good day.

Web sockets, socket.io or other alternative

I'm kinda new on sockets related subject so I'm sorry for any dumb question.
I would like to do something like this… I have am hybrid app and a website, and I wanted that when I click in a button on the app, it shows me alert/notificaion on the website. I read about Socket io and it does the job on localhost, but I want na alternative that not uses a server behind, since I'm not being able to run it using CPANEL (What I have access to)
Is it possible to have like a "direct" connection from the app to the site when I click the button?
You can consider using firebase for this:
In your javascript:
// execute the following script on click
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
'messagingSenderId': 'YOUR-SENDER-ID'
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
messaging.send({data: "your data if you want to send"}).then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
// similarly, on your browser:
messaging.onMessage(function(payload) {
console.log('Message received. ', payload);
// ...
});
link: https://firebase.google.com/docs/
Hope it helps
Let's break the problem down into a few parts, starting with the transport to the browser, as that's what you're asking about.
Web Sockets are a way to establish a bi-directional connection between a server and a client. It's a standard implemented by most any modern browser. Socket.IO is a web-socket-like abstraction that can use Web Sockets or other transports under the hood. It was originally built as sort of a polyfill, allowing messages to be sent via Web Sockets, or even long-polling. Using Socket.IO doesn't give you any additional capability than you have with just the browser, but it does provide some nice abstractions for "rooms" and such.
If you're sending data only from the server to the client, Web Sockets aren't the ideal choice. For streaming of data in general, the Fetch API and ReadableStream are more appropriate. Then, you can just make a normal HTTP connection. However, what you're looking for is event-style data, and for that there are Server-Sent Events (SSE). https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events Basically, you instantiate an EventSource object on the client, pointed at a URL on the server. The client automatically maintains a connection, reconnecting if necessary. It's also capable of synchronizing to a point in the stream, providing the server with the last message received so that the client can be caught up to present time.
Now, how does your server endpoint know when to send this data, and what to send? Ideally, you'll use some sort of pub/sub system. These capabilities are built into Redis, which is commonly used for this. (There are others as well, if you don't like Redis for some reason.) Basically, when your server receives something from the app, the app is "publishing" a message to a particular channel where all "subscribers" will receive it. Your server will be that EventSource and can simply relay data (verifying it and authenticating of course, along the way).
You can write a PHP script that has a POST/GET endpoint. Your app will communicate to this endpoint. The endpoint needs to handle the message and write it to a database. Your website can then poll to see if there are any new entries, and show something if there are
Alright, let's do it in PHP. This is just the most basic example. Just put it somewhere and link to the script from your app.
<?php
function requestVars($type = 'REQUEST'){
if($type == 'REQUEST')
$r = $_REQUEST;
elseif($type == 'POST')
$r = $_POST;
elseif($type == 'GET')
$r = $_GET;
$ret = array();
foreach($r as $r1 => $r2)
$ret[$r1] = $r2;
return $ret;
}
$vars = requestVars(); //get variables from request
echo $vars['var1']; // var1 is what comes in from the client
?>
I haven't tested this, so if something is wrong let me know.

Websocket on MAMP

I am working on a personal project that has a chat message system. I want the messages to update real time for both users when a new message is sent (like facebook chat). Although I have tried multiple ways to detect changes on the database and AJAX my PHP script that SELECTs the messages I can only update the sender's message in real time. The receiver can't see the new message unless they refresh their page. So I decided to use websockets on my local environment to keep the connection open and AJAX my messages.php script when there is a change on the database. However, when I create the websocket object:
var msgsSocket = new WebSocket("ws://www.localhost:8888/messages.php");
I am getting an error:
WebSocket connection to 'ws://www.localhost:8888/messages.php' failed: Error during WebSocket handshake: Unexpected response code: 200
I also tested with the following URL strings:
www.localhost/messages.php
localhost:8888/messages.php
I am not sure what I am doing wrong. Any help is welcome.
P.S. I am using MAMP

How do I send a channel message using channel.trigger with websocket-rails gem

I'm building a simple real-time chat app to learn how to use websockets with RoR and I don't think I'm understanding how channels work because they're not doing what I expect. I can successfully send a message to my Rails app using the dispatcher.trigger() method, and use my websocket controller to broadcast a message to all clients that subscribe to the channel. That all works fine. What does NOT work is using a channel (via the channel.trigger() method) to send a message to other clients. The websocket-rails wiki says...
Channel events currently happen outside of the Event Router flow. They
are meant for broadcasting events to a group of connected clients
simultaneously. If you wish to handle events with actions on the
server, trigger the event on the main dispatcher and specify which
controller action should handle it using the Event Router.
If I understand this correctly, I should be able to user the channel.trigger() method to broadcast a message to clients connected to the channel, without the message being routed through my RoR app, but it should still reach the other connected clients. So here's my code...
var dispatcher = new WebSocketRails('localhost:3000/websocket');
var channel = dispatcher.subscribe('channel_name');
channel.bind('channel_message', function(data) {
alert(data.message);
});
$("#send_message_button").click(function() {
obj = {message: "test"};
channel.trigger('channel_message', obj);
});
With the code listed above, I would expect that when I click the button, it sends a channel message using channel.trigger() and the channel_message binding should be executed on all clients, displaying an alert that reads "test". That doesn't happen. I'm using Chrome tools to inspect the websocket traffic and it shows the message being sent...
["channel_message",{"id":113458,"channel":'channel_name',"data":{"message":"test"},"token":"96fd4f51-6321-4309-941f-38110635f86f"}]
...but no message is received. My questions are...
Am I misunderstanding how channel-based websockets work with the websocket-rails gem?
If not, what am I doing wrong?
Thanks in advance for all your wisdom!
I was able to reproduce a working copy based on an off-the-shelf solution from the wiki along with your very own code.
I've packaged the whole thing here. The files you might be interested are home_controller.rb, application.js and home/index.html.erb.
It seems your understanding of channel-based websockets is correct. About the code, make sure to load the websocket javascript files and to enclose your code inside a document.ready. I had the exact same problem you're having without the latter.
//= require websocket_rails/main
$(function() {
// your code here...
});
Let me know if it works. Best Luck!

CFWEBSOCKET - unable to call websocket object in Javascript

I'm using the cfwebsocket tag in Coldfusion to create a web socket connection.
I looked at an example from here http://www.sagarganatra.com/2012/03/html5-websockets-in-coldfusion-10.html
and near the end it shows you all the javascript calls you can make on the web socket object.
However, when I try to make any call on it I get an error that it is undefined.
For example I have:
<cfwebsocket name="ws" onMessage="messageHandler" onOpen="openHandler" onClose="closeHandler" onError="errorHandler" subscribeTo="chat" />
and in my javascript i call
alert(ws.isConnectionOpen());
and I get the error in firebug: TypeError: ws is undefined.
Anyone know why I can't call it?
My chat works fine and I can connect and chat properly. I just wanted to close the connection when the chat ended so I was looking into how it's done calling the websocket but I don't know why it's not working.
Note that I am using jQuery and the javascript is wrapped in the document ready.
First, you can't interact with the ws object till it establishes a connection to the server.
There are a couple of ways to handle this scenario. You can use the "onOpen" attribute and have it call a function once the web socket connect has been established.
However, you are probably better off just using the "onMessage" attribute and create a generic listener function that processes all web socket messages from the server.
function messageHandler(msg) {
if (msg.type == 'response' && msg.reqType == 'welcome'){
alert('user connected');
}
}

Categories

Resources