
Security News
Nx npm Packages Compromised in Supply Chain Attack Weaponizing AI CLI Tools
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.
Orator is a websocket client/server combination that uses events in order to talk to each other. It is still early in its development.
This project uses web-socket-js as well as em-websocket.
Orator integrates easily with Ruby on Rails. Just add
gem 'orator'
to your Gemfile and bundle install
away. In order to use it, you'll need to
add the following line to your application.js
file:
//= require orator
Now you can use the orator client in your JavaScript! If the browser doesn't support JavaScript, it'll fall back to a flash object.
We'll start with the server-side stuff. A simple rails g orator:config
will
place the file orator_config.yml
in config/
, and an example orator in
app/orators
. Feel free to modify the configuration file (I'll add
documentation to it). Let's set up a orator here:
class TestOrator < Orator::Base
This is important. Orator will not accept the Handler unless it is a child
of Orator::Base
. Orator::Base
implements methods that
are used by Orator.
before do
self.number_of_messages ||= 0
self.number_of_messages += 1
if self.number_of_messages > 9_000
prevent_event
end
end
Here we have a basic before block that increments a number every time we get a message. If the number of messages is over 9,000, it will prevent the event from occuring (but any after blocks will still run).
on :ping
def ping(data)
send message('test.pong', message: 'pong')
end
Here we define a basic event named ping
. When the server receives it, it
sends back an event named test.pong
, with the message pong
. Cool, eh?
on :pong
def pong(data)
puts data["message"] # => "pong"
end
In this we're assuming that somewhere else in our code the client sent us a
test.pong
event; maybe they did so in response to a ping that we sent.
Either way, we're outputting a message that we received.
end
Orator.add_orator(TestOrator)
Here we register our orator with Orator, so it can use it for routing events.
But say we also want to handle a socket.open
event. Our orator above can't
handle that, sadly, so we use this method:
Orator.add_orator do |events|
events.on('socket.open') do |data|
self.user = {}
send mesasge('test.ping', message: 'ping')
end
events.on('user.alias') do |data|
self.user[:name] = json["name"]
end
end
So when the socket opens in socket.open
, we set #user
to an empty hash and
send a ping message (whose response will be handled by our TestOrator). When
we receive the user.alias
message, we set the key-pair :name => json["name"]
on the #user
hash. Cool, eh?
To run the server, run orator --command start
in the root rails directory.
To daemonize it, run orator --command start -d
. To stop, run
orator --command stop
.
Let's go through an example together.
$(document).ready(function() {
Orator.setup("ws://host:port/path?query", function(events){
Orator.setup
handles setting up our socket for us. It also sets up the
events and routing, as well. There are some locally defined events that are
triggered even if the server hadn't sent them, such as socket.open
and
socket.close
.
events.on('some.event', function() {})
Here we're binding some event named some.event
to an empty function. Boring.
Note that the name of the event doesn't matter here.
events.on('test.ping', function() {
this.server.send('test.pong', { message: 'pong' });
});
Here we're responding to a ping that a server might send to this client. We
send back a test.pong
event, with the message 'pong'. The contents of the
event can be anything.
events.on('test.pong', function(data) {
console.log(data.message) // => "pong"
});
Here we received a pong back from the server - this was triggered by the server in response to our ping, which we could have sent at any time.
events.on('socket.open', function() {
this.user = {}
this.server.send('user.alias', { name: some_name })
});
Here we defined an event that will set up a an empty object on the property
user of this
. This will become important. We then send the event
user.alias
to the server (which probably changes the name of the user) with
the new name (assuming some_name
has a string value).
events.on('user.alias', function(data) {
this.user.name = data.name;
});
It is common place for the server's response events to be named the same as the request events (although the response events may be sent at any time, with no context). Here we see setting the name of the user object to the name the server sent back. This is the same user object that we defined in the event above.
});
});
And we close our braces.
FAQs
Unknown package
We found that orator demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.
Security News
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.