1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-04 17:27:23 -05:00

refactor mux code

This commit is contained in:
Darien Raymond 2017-04-03 23:43:33 +02:00
parent 682235cacc
commit bf0a4c428e
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169

View File

@ -94,13 +94,18 @@ func (m *ClientManager) onClientFinish() {
m.access.Lock() m.access.Lock()
defer m.access.Unlock() defer m.access.Unlock()
nActive := 0 if len(m.clients) < 10 {
for idx, client := range m.clients { return
if nActive != idx && !client.Closed() { }
m.clients[nActive] = client
activeClients := make([]*Client, 0, len(m.clients))
for _, client := range m.clients {
if !client.Closed() {
activeClients = append(activeClients, client)
} }
} }
m.clients = m.clients[:nActive] m.clients = activeClients
} }
type Client struct { type Client struct {
@ -209,12 +214,40 @@ func (m *Client) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) bool
return true return true
} }
func drain(reader *Reader) error {
for {
data, more, err := reader.Read()
if err != nil {
return err
}
data.Release()
if !more {
return nil
}
}
}
func pipe(reader *Reader, writer buf.Writer) error {
for {
data, more, err := reader.Read()
if err != nil {
return err
}
if err := writer.Write(data); err != nil {
return err
}
if !more {
return nil
}
}
}
func (m *Client) fetchOutput() { func (m *Client) fetchOutput() {
reader := NewReader(m.inboundRay.InboundOutput()) reader := NewReader(m.inboundRay.InboundOutput())
for { for {
meta, err := reader.ReadMetadata() meta, err := reader.ReadMetadata()
if err != nil { if err != nil {
log.Warning("Proxyman|Mux|Client: Failed to read metadata: ", err) log.Info("Proxyman|Mux|Client: Failed to read metadata: ", err)
break break
} }
m.access.RLock() m.access.RLock()
@ -228,21 +261,17 @@ func (m *Client) fetchOutput() {
continue continue
} }
for {
data, more, err := reader.Read()
if err != nil {
break
}
if found { if found {
if err := s.output.Write(data); err != nil { err = pipe(reader, s.output)
} else {
err = drain(reader)
}
if err != nil {
log.Info("Proxyman|Mux|Client: Failed to read data: ", err)
break break
} }
} }
if !more {
break
}
}
}
} }
type Server struct { type Server struct {
@ -295,22 +324,9 @@ func handle(ctx context.Context, s *session, output buf.Writer) {
writer := NewResponseWriter(s.id, output) writer := NewResponseWriter(s.id, output)
defer writer.Close() defer writer.Close()
for { _, timer := signal.CancelAfterInactivity(ctx, time.Minute*30)
select { if err := buf.PipeUntilEOF(timer, s.input, writer); err != nil {
case <-ctx.Done():
log.Debug("Proxyman|Mux|ServerWorker: Session ", s.id, " ends by context.")
return
default:
data, err := s.input.Read()
if err != nil {
log.Info("Proxyman|Mux|ServerWorker: Session ", s.id, " ends: ", err) log.Info("Proxyman|Mux|ServerWorker: Session ", s.id, " ends: ", err)
return
}
if err := writer.Write(data); err != nil {
log.Info("Proxyman|Mux|ServerWorker: Session ", s.id, " ends: ", err)
return
}
}
} }
} }
@ -357,20 +373,19 @@ func (w *ServerWorker) run(ctx context.Context) {
go handle(ctx, s, w.outboundRay.OutboundOutput()) go handle(ctx, s, w.outboundRay.OutboundOutput())
} }
if meta.Option.Has(OptionData) { if !meta.Option.Has(OptionData) {
for { continue
data, more, err := reader.Read()
if err != nil {
break
} }
if s != nil { if s != nil {
if err := s.output.Write(data); err != nil { err = pipe(reader, s.output)
} else {
err = drain(reader)
} }
}
if !more { if err != nil {
log.Info("Proxyman|Mux|ServerWorker: Failed to read data: ", err)
break break
} }
} }
} }
}
}