github.com/unirita/cuto@v0.9.8-0.20160830082821-aa6652f877b7/servant/remote/receive.go (about)

     1  // マスタからの受信
     2  // Copyright 2015 unirita Inc.
     3  // Created 2015/04/10 shanxia
     4  
     5  package remote
     6  
     7  import (
     8  	"bufio"
     9  	"fmt"
    10  	"net"
    11  	"time"
    12  
    13  	"github.com/unirita/cuto/console"
    14  	"github.com/unirita/cuto/log"
    15  )
    16  
    17  // 送受信メッセージの終端文字
    18  const MsgEnd = "\n"
    19  
    20  const protocol = "tcp"
    21  
    22  // 引数で指定したbind用のアドレスとポート番号portを指定してメッセージの受信待ちを開始する。
    23  // 受信したメッセージは戻り値のchan stringに順番に挿入されていく。
    24  // 引数で指定した多重度でチャネルを作成する。
    25  //
    26  // 引数:bindAddr バインドアドレス
    27  //
    28  // 引数:port Listenポート番号
    29  //
    30  // 引数:multi メッセージ受信の多重度
    31  //
    32  // 戻り値:メッセージ受信を通知する、受信チャネル
    33  //
    34  // 戻り値:エラー情報
    35  func StartReceive(bindAddr string, port int, multi int) (<-chan *Session, error) {
    36  	addr := fmt.Sprintf("%s:%d", bindAddr, port)
    37  
    38  	listener, err := net.Listen(protocol, addr)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	console.Display("CTS007I", bindAddr, port)
    43  
    44  	sq := make(chan *Session, multi)
    45  	go receiveLoop(listener, sq)
    46  
    47  	return sq, nil
    48  }
    49  
    50  func receiveLoop(listener net.Listener, sq chan<- *Session) {
    51  	for {
    52  		receiveLoopProcess(listener, sq)
    53  	}
    54  }
    55  
    56  func receiveLoopProcess(listener net.Listener, sq chan<- *Session) error {
    57  	conn, err := listener.Accept()
    58  	if err != nil {
    59  		log.Error(err)
    60  		return err
    61  	}
    62  
    63  	console.Display("CTS014I")
    64  	go receiveMessage(conn, sq)
    65  	return nil
    66  }
    67  
    68  func receiveMessage(conn net.Conn, sq chan<- *Session) error {
    69  	const timeout = 10
    70  
    71  	deadLine := time.Now().Add(timeout * time.Second)
    72  	if err := conn.SetReadDeadline(deadLine); err != nil {
    73  		log.Error(fmt.Sprintf("[%v]: %v\n", conn.RemoteAddr(), err))
    74  		return err
    75  	}
    76  
    77  	scanner := bufio.NewScanner(conn)
    78  	if !scanner.Scan() {
    79  		log.Error(fmt.Sprintf("[%v]: %v\n", conn.RemoteAddr(), scanner.Err()))
    80  		return scanner.Err()
    81  	}
    82  	sq <- NewSession(conn, scanner.Text())
    83  	return nil
    84  }