Prosty czat - kod klienta

Cześć, napisałem sobie prosty konsolowy serwer czatu z użyciem gserver.

Zachodzę w głowę jak teraz napisać fragment kodu klienta, który pobiera linię z klawiatury (gets) i równocześnie wyświetla przychodzące z serwera (socket.gets) wiadomości… Help :slight_smile:

http://www.ruby-doc.org/core/classes/Thread.html może to?

edit:
albo to: http://rubyeventmachine.com/ ?

No właśnie coś mi Thread nie krzesi. Luknij proszę może robię jakiś błąd:

[code=ruby]module SlimChat
class Client
def initialize
@socket = TCPSocket.open(‘127.0.0.1’, 10001)
end

def start
  p "Welcome! Start you chat now: "

  Thread.new do
    socket_message = @socket.gets.chop
    p socket_message if socket_message.size > 0
    sleep 1
  end

  @socket.puts msg while (msg = gets.chop) != "bye"

  @socket.close
end

end
end[/code]

Pokaż może więcej kodu : )

Nowy wątek jest tworzony przy nawiązaniu nowego połączenia, więc odbieranie wiadomości powinno być w nim.
Jak ja to robiłem (niestety już nie mam kodu), to obsługiwałem w kliencie odbieranie danych przez server.waitfor, gdzie server było telnetowym połączeniem z serwerem. Coś takiego, ale wszystko działało ; )
Pokaż więcej kodu, najlepiej cały : )

Wrzuciłem więcej kodu w wyższym poście.

W kliencie nie korzystaj z wątków, bo łączysz się tylko z jednym serwerem - wątków musisz użyć tylko w serwerze, bo on łączy się z wieloma wątkami, i powinien mieć oddzielny thread dla każdego połączenia - z tego co wiem, to na dłuższą metę i trochę większy chat niż konfa z kumplami thready są niewydajne (bo jest ich dużo) i trzeba korzystać z czegoś innego, ale szczerze mówiąc nie mam pojęcia z czego w konsoli, np. w QT są wbudowane narzędzia do tego. Poszukaj coś o tym waitfor, bo jestem pewien, że tak to obsługiwałem - coś w stylu:

  1. wyślij dane do serwera

[code]if server.waitfor(/./)

znaczy że server przysłał nam jakieś dane i trzeba je obrobić

else

ponownie punkt 1

end[/code]

Nie chwytam Świstak albo nie zrozumiałeś. Serwer jest ok. Jak się telnetuję to wszystko gra.
Nie umiem w kliencie jednocześnie odczytywać wiadomości z serwera (żeby się na bieżąco pojawiały) i odczytywać znaków z klawiatury (gets) bo gets czeka na enter. Wątek z @socket.gets nie działa, bo nie pojawiają się wiadomości z serwera jak wysyłam z innego podłączonego klienta.

Przepraszam, myślałem, że na początek piszesz taki prostszy czat, i przez równocześnie, masz na myśli “równocześnie z wysłaniem wiadomości”, a nie podczas, mój błąd.

Spróbuj coś w ten deseń, ale tu dość strzelam, bo nie mam gotowego serwerka a niezbyt mi się chce go pisać tylko do testów.

[code]require ‘net/telnet’
@server = Net::Telnet::new(‘Host’ => ‘127.0.0.1’, ‘Port’ => 10001, ‘Telnetmode’ => false)

Thread.new do
begin
@server.waitfor(/./) do |data|
puts data
end
sleep 1
rescue Errno::Timeout #Tutaj ewentualnie musisz zmienić, bo nie pamiętam, jak był error, na pewno wyskoczy
end
end

@server.puts msg while (msg = gets.chop) != “bye”[/code]
EDIT: No i teraz widzę, że robiłem to całkiem inaczej, bo nie wiedziałem nawet o istnieniu TCPSocket.

EDIT2: Ewentualnie, jak tak patrzę - to działa ok? Po Thread.new w środku powinna być jakaś pętla loop do… wydaje mi się, aby ciągle odbierał te wiadomości. I co ważne, co się później podczas korzystania z wątków dowiedziałem - w threadach jakoś nie idzie korzystać z innych metod - wątek się wtedy kończy, ale możliwe, że coś źle robiłem.

Dzięki Świstak! Dzięki Tobie znalazłem błąd, brakowało mi while’a w wątku czytającym z serwera, teraz śmiga jak należy :slight_smile:

[code=ruby] def start
p "Welcome! Start you chat now: "

  Thread.new do
    while @socket.closed? == false
      socket_message = @socket.gets.chop
      p socket_message if socket_message.size > 0
      sleep 1
    end
  end

  # read client's until "bye" command
  while (msg = gets.chop) do
    @socket.puts msg
    break if msg == "bye"
  end

  # hasta la vista, socket :)
  @socket.close
end[/code]

Może by tak eventmachine ?