I'm trying to create a socket in Ruby using
require "socket"
w = UNIXSocket.new("socket")
and I keep running into
No such file or directory - socket (Errno::ENOENT)
This looks completely backwards to me, because new() is supposed to create that missing file. What am I missing?
This is super old. Please don't try to use it verbatim anymore.
http://blog.antarestrader.com/posts/153
#!/ruby
file = 'path/to/my/socket'
File.unlink if File.exists(file) && File.socket?(file)
server = UNIXServer.new(file)
# return a UNIXSocket once a connection is made
socket = server.accept
# socket is now ready to communicate.
UnixServer makes the socket, UnixSocket only connects to an existing socket.
Related
I'm trying to learn more about the Jupyter wire protocol. I want to collect examples of the messages sent on the IOPub socket.
SETUP:
I start a Jupyter console in one terminal then go find the connection file. In my case the contents are as follows:
{
"shell_port": 62690,
"iopub_port": 62691,
"stdin_port": 62692,
"control_port": 62693,
"hb_port": 62694,
"ip": "127.0.0.1",
"key": "9c6bbbfb-6ad699d44a15189c4f3d3371",
"transport": "tcp",
"signature_scheme": "hmac-sha256",
"kernel_name": ""
}
I create a simple python script as follows:
import zmq
iopub_port = "62691"
ip = "127.0.0.1"
transport = "tcp"
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect(f"{transport}://{ip}:{iopub_port}")
while True:
string = socket.recv()
print(string)
I open a second terminal and execute the script as follows (it blocks, as expected):
python3 script.py
And then I switch back to the first terminal (with the Jupyter console running) and start executing code.
ISSUE: Nothing prints on the second terminal.
EXPECTED: Some Jupyter IO messages, or at least some sort of error.
Uh, help? Is my code fine and this is probably an issue with my config? Or is my code somehow braindead?
From one of the owners of the Jupyter client repo:
ZMQ subscriber sockets need a subscription set before they'll receive
any messages. The subscription is a prefix of a valid message, and you
can set it to an empty bytes string to subscribe to all messages.
e.g. in my case I need to add
socket.setsockopt(zmq.SUBSCRIBE, b'')
before starting the while loop.
Do you know if it's possible to capture from IOPub if a process in Jupyter notebook is finished or not?
I'm looking here (http://jupyterlab.github.io/jupyterlab/services/modules/kernelmessage.html) but it is not very clear.
Situation
I connect to a WebSocket with Chrome's Remote Debugging Protocol, using a Rails application and a class that implements Celluloid, or more specifically, celluloid-websocket-client.
The problem is that I don't know how to disconnect the WebSocket cleanly.
When an error happens inside the actor, but the main program runs, Chrome somehow still makes the WebSocket unavailable, not allowing me to attach again.
Code Example
Here's the code, completely self-contained:
require 'celluloid/websocket/client'
class MeasurementConnection
include Celluloid
def initialize(url)
#ws_client = Celluloid::WebSocket::Client.new url, Celluloid::Actor.current
end
# When WebSocket is opened, register callbacks
def on_open
puts "Websocket connection opened"
# #ws_client.close to close it
end
# When raw WebSocket message is received
def on_message(msg)
puts "Received message: #{msg}"
end
# Send a raw WebSocket message
def send_chrome_message(msg)
#ws_client.text JSON.dump msg
end
# When WebSocket is closed
def on_close(code, reason)
puts "WebSocket connection closed: #{code.inspect}, #{reason.inspect}"
end
end
MeasurementConnection.new ARGV[0].strip.gsub("\"","")
while true
sleep
end
What I've tried
When I uncomment #ws_client.close, I get:
NoMethodError: undefined method `close' for #<Celluloid::CellProxy(Celluloid::WebSocket::Client::Connection:0x3f954f44edf4)
But I thought this was delegated? At least the .text method works too?
When I call terminate instead (to quit the Actor), the WebSocket is still opened in the background.
When I call terminate on the MeasurementConnection object that I create in the main code, it makes the Actor appear dead, but still does not free the connection.
How to reproduce
You can test this yourself by starting Chrome with --remote-debugging-port=9222 as command-line argument, then checking curl http://localhost:9222/json and using the webSocketDebuggerUrl from there, e.g.:
ruby chrome-test.rb $(curl http://localhost:9222/json 2>/dev/null | grep webSocket | cut -d ":" -f2-)
If no webSocketDebuggerUrl is available, then something is still connecting to it.
It used to work when I was using EventMachine similar to this example, but not with faye/websocket-client, but em-websocket-client instead. Here, upon stopping the EM loop (with EM.stop), the WebSocket would become available again.
I figured it out. I used the 0.0.1 version of the celluloid-websocket-client gem which did not delegate the close method.
Using 0.0.2 worked, and the code would look like this:
In MeasurementConnection:
def close
#ws_client.close
end
In the main code:
m = MeasurementConnection.new ARGV[0].strip.gsub("\"","")
m.close
while m.alive?
m.terminate
sleep(0.01)
end
I'm trying to go through this particular code example from "The Well Grounded Rubyist" regarding TCPServer and threads. The code is below:
require 'socket'
server = TCPServer.new(3939)
connect = server.accept
connect.puts "Hi. Here's the date."
connect.puts 'date'
connect.close
server.close
How do I know what port is on my Macbook? The docs has 2000 in the example. However, when I try both of these numbers the code doesn't execute, it continues to hang indefinitely.
How can I check if these numbers are verified ports? I tried telnetting to the port number and the connection is refused everytime.
server.accepts waits for a client to connect to the server. If that does not happen, it just keeps waiting. Run the code, then open terminal and type:
require 'socket'
s = TCPSocket.new 'localhost', 3939
At this point you will create TCPSocket, which will connect with your server. This will cause the rest of the code to execute. You can check it with your socket:
while line = s.gets # Read lines from socket
puts line # and print them
end
I'm on Fedora 20 and use ruby 2.1.0. I've the following code from ruby-doc.
require 'socket'
s = TCPSocket.new 'localhost', 2000
while line = s.gets # Read lines from socket
puts line # and print them
end
s.close # close socket when done
Ruby throws the following error:
client.rb:3:in `initialize': Connection refused - connect(2) for "localhost" port 2000 (Errno::ECONNREFUSED)
from client.rb:3:in `new'
from client.rb:3:in `<main>'
What could be the reason for this failure? I mean, the code should definitively work, it's dead simple and from a recognized tutorial web page for ruby. I guess that the problem is my operating system, but how do I get it working properly?
Sockets are the endpoints of a bidirectional communications channel. Sockets may communicate within a process, between processes on the same machine, or between processes on different continents.
A Simple Client:
require 'socket' # Sockets are in standard library
hostname = 'localhost'
port = 2000
s = TCPSocket.open(hostname, port)
while line = s.gets # Read lines from the socket
puts line.chop # And print with platform line terminator
end
s.close
Now call TCPServer.open hostname, port function to specify a port for your service and create a TCPServer object.
A Simple Server:
require 'socket' # Get sockets from stdlib
server = TCPServer.open(2000) # Socket to listen on port 2000
loop { # Servers run forever
client = server.accept # Wait for a client to connect
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
client.close # Disconnect from the client
}
read doc
I'm attempting to create a script in ruby that connects to a Minecraft server via TCP and fetches the current number of players much like the PHP script at http://www.webmaster-source.com/2012/07/05/checking-the-status-of-a-minecraft-server-with-php/
When running the code below I get �Took too long to log in
require 'socket'
server = TCPSocket.new '192.241.174.210', 25565
while line = server.gets
puts line
end
server.close
What am I doing wrong here?
you're not sending this:
fwrite($sock, "\xfe");
from the script you linked. You have to send that before you call read, like they do.
Basically the server is waiting for you to send data and when you don't after a timeout, you are disconnected.