mbilab / ptt-bot

55 stars 12 forks source link

New node package: 'node-telnet-client' #4

Open chenchenbox opened 10 years ago

chenchenbox commented 10 years ago

'node-telnet-client'(https://github.com/mkozjak/node-telnet-client) 實作了telnet client端,應該是根據RFC 854 spec(http://tools.ietf.org/html/rfc854) , 根據作者的回信,利用偵測telnet sever回傳的data偵測prompt, 來判斷是否已經收集完資料.

信件紀錄: Ask from chenchen:

Hi,

I just found your contribution about telnet connection in client from npm.

I am current working on a project which involves create a socket(connection) to a BBS sever. I have some problem want to discuss with you. Since I am not familiar to tcp connection, my problem may sounds stupid. Please forgive me if these are really fundamental.

Here are my problem.

  1. I've tried to use native node package called "net" to realize the socket between my computer(client) to BBS sever before, and it quite doing good. And l've seen the intro about your package. They are quite similar. What is the main difference between your contribution 'telnet-client' and native package 'net'?
  2. I've meeting trouble recently about handling received data from bbs sever. How can I detect the bbs sever has just finished senting data? In details, when my client has sent an command to bbs sever, sever will respond a bulls of data. And I used to use 'data' event from connection listener, it will be trigger while a chunk of data has been received. My purpose is to reconstruct the whole screen of terminal, and I found I usually only got part of screen of terminal when 'data' event is triggered. Is there any way I can detect if this is the end of screen(in other words, the data was received completely). Is this in related to the Buffer concept in readable stream?

I am looking forward your respond. Hope everything is good with you.

Reply from mkozjak(kozjakm1@gmail.com):

Hi!

telnet-client uses 'net' as its basis. telnet-client is a telnet implementation, thus, it provides you with simple functions to get responses from telnet sessions. Without it, you'd need to take care of telnet on your own, and that's, like, 200 lines of additional code. That's the basic difference.

How I am looking for finished response is waiting for the prompt. Once I receive it, I declare an end of response. https://github.com/mkozjak/node-telnet-client/blob/master/lib/telnet-client.js (line 154)

Have you tried using net's socket.setTimeout()? If you open a connection each time you want to get some data, then the timeout is pretty much an indication you're not receiving anything. Just set a timeout each time the socket is opened.

Hope some of this helps!

With regards, Mario Kozjak

補: Event: 'timeout' (http://nodejs.org/api/net.html#net_event_timeout):

Emitted if the socket times out from inactivity. This is only to notify that the socket has been idle. The user must manually close the connection.

See also: socket.setTimeout()

補: 經過測試, timeout參數設定為500ms較為OK., 應當更改程式, 當timeout觸發時才執行傳送下一個ptt指令,而非一接獲資料就傳送.

chenchenbox commented 10 years ago

目前卡在每次data事件被處發時,所得到的資料都沒有很完整,我需要等到screen收集完才可以執行下一個ptt command.

根據node net(http://nodejs.org/api/net.html#net_class_net_socket) :

createConnection() is a factory method, which returns a new 'net.Socket' and connects to the supplied address and port. Has the same events as 'net.Socket'.

而net.Socket為(http://nodejs.org/api/net.html#net_class_net_socket):

Class: net.Socket This object is an abstraction of a TCP or UNIX socket. net.Socket instances implement a duplex Stream interface. They can be created by the user and used as a client (with connect()) or they can be created by Node and passed to the user through the 'connection' event of a server.

根據node stream(http://nodejs.org/api/stream.html#stream_class_stream_duplex):

Class: stream.Duplex Duplex streams are streams that implement both the Readable and Writable interfaces. See above for usage. 

且Readable interface 的其中一個 event 為 'end' (http://nodejs.org/api/stream.html#stream_event_end) 和net.socket的 'end' event (http://nodejs.org/api/net.html#net_event_end) 用途不一樣.

似乎雖為繼承關係,event 被實作的方式不同,不明白為何,如果可以就Readable interface的定義,我可以就批踢踢傳完資料時,直接觸發事件。但net.socket的'end'就是不一樣的樣子.

補:  interface 與 abstract class 的差異. => http://www.flag.com.tw/book/cento-5105.asp?bokno=FS720&id=312

chenchenbox commented 10 years ago

Readable interface 'end' event (http://nodejs.org/api/stream.html#stream_event_end) :

This event fires when there will be no more data to read.

Note that the end event will not fire unless the data is completely consumed. This can be done by switching into flowing mode, or by calling read() repeatedly until you get to the end.

var readable = getReadableStreamSomehow();
readable.on('data', function(chunk) {
  console.log('got %d bytes of data', chunk.length);
})
readable.on('end', function() {
  console.log('there will be no more data.');
});

net.socket 'end' event (http://nodejs.org/api/net.html#net_event_end):

Emitted when the other end of the socket sends a FIN packet.

By default (allowHalfOpen == false) the socket will destroy its file descriptor once it has written out its pending write queue. However, by setting allowHalfOpen == true the socket will not automatically end() its side allowing the user to write arbitrary amounts of data, with the caveat that the user is required to end() their side now.

chenchenbox commented 10 years ago

結論: 經過測試, timeout參數設定為500ms較為OK., 應當更改程式, 當timeout觸發時才執行傳送下一個ptt指令,而非一接獲資料就傳送.

chenchenbox commented 10 years ago

可以考慮試試看連線改用'node-telnet-client',