あなたの投稿は、実際にいくつかの質問をする:
- 接続プールを管理するためにどのように?
- ソケットを介した通信を処理するにはどうすればよいですか?
これらは実際には2つの異なるものです。接続プールは、一連の接続を管理する単なる方法です。これを実装する簡単な方法は次のようなクラスです:
package netpool
import (
"net"
)
const MaxConnections = 3
type Error string
func (e Error) Error() string {
return string(e)
}
var ErrMaxConn = Error("Maximum connections reached")
type Netpool struct {
name string
conns int
free []net.Conn
}
func NewNetpool(name string) *Netpool {
return &Netpool{
name: name,
}
}
func (n *Netpool) Open() (conn net.Conn, err error) {
if n.conns >= MaxConnections && len(n.free) == 0 {
return nil, ErrMaxConn
}
if len(n.free) > 0 {
// return the first free connection in the pool
conn = n.free[0]
n.free = n.free[1:]
} else {
addr, err := net.ResolveTCPAddr("tcp", n.name)
if err != nil {
return nil, err
}
conn, err = net.DialTCP("tcp", nil, addr)
if err != nil {
return nil, err
}
n.conns += 1
}
return conn, err
}
func (n *Netpool) Close(conn net.Conn) error {
n.free = append(n.free, conn)
return nil
}
ここではスタンドアロンクラスを作成しました。通常、MyHTTPHostやMyDatabaseなどの上位クラスの一部として実装されます。
この単純な実装では、netpool.Open()によって返される接続は追跡されません。 Open()を呼び出し、netpool.Close()の外部で接続を閉じることで、接続がリークする可能性があります。たとえば、この問題を解決するアクティブプールと非アクティブプールを保持したい場合は、そのプールを追跡することが可能です。
あなたはプーリングの実装に追加するかもしれない他の物事のカップル:(例えばsync.Mutexを使用して、)
- スレッディング保護の非アクティブのいくつかの長さの後にフリープール内の接続の
- 閉会
- あなたが接続されていたら、Readを呼び出すと、通常はそれを書くことができます
クローズ接続がまだ有効であることを確認するためにエラーチェック。ソケット上の残っているデータをすべて消去するには、単にioutil.ReadAll()ヘルパ関数を使うだけです。デフォルトでは、利用可能なデータがない場合、これは無期限にブロックされます。それを避けるために、使用して読み込みタイムアウトを追加します。
conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
_, err = ioutil.ReadAll(conn)
neterr, ok := err.(net.Error)
if ok && neterr.Timeout() {
err = nil // timeout isn't an error in this case
}
if err != nil {
// handle the error case.
}
いずれかが保留されている、またはデータが保留されなかった場合は、I/Oタイムアウトエラーで500ミリ秒後に戻ります場合、これは特定の接続からのすべてのデータを読み込みます。
iautil.ReadAll()はnet.ErrorインターフェイスではなくErrorインターフェイスを返すので、型アサーションが必要です。タイムアウトにより呼び出しが返されたかどうかを簡単に確認できるように、後者が必要です。
ようこそ!あなたのコードを少し見せてくれれば幸いです。 – vyegorov