| 466 | } |
| 467 | |
| 468 | func (w *websocketWriter) Write(p []byte) (int, error) { |
| 469 | if w.noMoreSend { |
| 470 | return 0, nil |
| 471 | } |
| 472 | var total int |
| 473 | var n int |
| 474 | var err error |
| 475 | // If there are control frames, they can be sent now. Actually spec says |
| 476 | // that they should be sent ASAP, so we will send before any application data. |
| 477 | if len(w.ctrlFrames) > 0 { |
| 478 | n, err = w.writeCtrlFrames() |
| 479 | if err != nil { |
| 480 | return n, err |
| 481 | } |
| 482 | total += n |
| 483 | } |
| 484 | // Do the following only if there is something to send. |
| 485 | // We will end with checking for need to send close message. |
| 486 | if len(p) > 0 { |
| 487 | if w.compress { |
| 488 | buf := &bytes.Buffer{} |
| 489 | if w.compressor == nil { |
| 490 | w.compressor, _ = flate.NewWriter(buf, flate.BestSpeed) |
| 491 | } else { |
| 492 | w.compressor.Reset(buf) |
| 493 | } |
| 494 | if n, err = w.compressor.Write(p); err != nil { |
| 495 | return n, err |
| 496 | } |
| 497 | if err = w.compressor.Flush(); err != nil { |
| 498 | return n, err |
| 499 | } |
| 500 | b := buf.Bytes() |
| 501 | p = b[:len(b)-4] |
| 502 | } |
| 503 | fh, key := wsCreateFrameHeader(w.compress, wsBinaryMessage, len(p)) |
| 504 | wsMaskBuf(key, p) |
| 505 | n, err = w.w.Write(fh) |
| 506 | total += n |
| 507 | if err == nil { |
| 508 | n, err = w.w.Write(p) |
| 509 | total += n |
| 510 | } |
| 511 | } |
| 512 | if err == nil && w.cm != nil { |
| 513 | n, err = w.writeCloseMsg() |
| 514 | total += n |
| 515 | } |
| 516 | return total, err |
| 517 | } |
| 518 | |
| 519 | func (w *websocketWriter) writeCtrlFrames() (int, error) { |
| 520 | var ( |