I'm building a web based Terminal that runs against other server by SSH. I'm using Xterm.js for the UI and Net::SSH for the backend. The communication between the website and the backend is inside an ActionCable channel (WebSocket).
Everything is working perfectly, including interactive tools like nano or vim, however, for some reason when running the command "bundle exec rails c" which is meant to open a Ruby on Rails console, it hangs. The terminal becomes unresponsive, I can see I am trying to type in the terminal because ssh_channel.send_data payload.dig("data", "cmd") gets called, but no data is received anymore in channel.on_data
Here are the relevant lines of code:
# Entry point
def start(payload)
connect!
open_channel!
open_connection_thread!
broadcast_reply(payload["id"], "login", { result: :successful })
end
# Every single key typed in Xterm.js is passed here.
def cmd(payload)
ssh_channel.send_data payload.dig("data", "cmd")
end
private
attr_accessor :ssh_client, :ssh_channel, :thread
def connect!
self.ssh_client ||= Net::SSH.start(
"host_ip",
"username",
keys_only: true,
use_agent: false,
key_data: [ssh_private_key]
)
end
def open_channel! # rubocop:disable Metrics/MethodLength
self.ssh_channel ||= ssh_client.open_channel do |channel|
channel.request_pty(term: "xterm-256color") do |ch, success|
raise "Error requesting pty" unless success
ch.send_channel_request("shell") do |_, result|
raise "Error opening shell" unless result
end
end
channel.on_data do |_, data|
broadcast_reply(nil, :cmd_output, data)
end
channel.on_extended_data do |_, _, data|
broadcast_reply(nil, :cmd_output, data)
end
channel.on_close { }
end
end
def open_connection_thread!
self.thread ||= Thread.new do
# This is blocking and could be done outside a thread because the callbacks are called anyway.
# However, this appears safer.
ssh_client.loop(0.1)
end
end
Here is how it looks like
Frozen when running Rails console
I don't really know what to look for. Any kind of clue would be really appreciated!
Note: I tried an existing online SSH client like this one https://ssheasy.com/ and it appears to be working as expected. What would be wrong with my implementation?
-
Are you able to you check (in a parallel normal SSH shell) what happens to the process itself?Igor– Igor2024年09月25日 17:38:18 +00:00Commented Sep 25, 2024 at 17:38
-
@Igor I can see the process is still running. What should I check (and how?)James St-Pierre– James St-Pierre2024年09月25日 18:05:14 +00:00Commented Sep 25, 2024 at 18:05