// writePump pumps messages from the hub to the websocket connection.
func (c *connection) writePump() {
	ticker := time.NewTicker(pingPeriod)
	defer func() {
		ticker.Stop()
		c.ws.Close()
	}()
	for {
		select {
		case threadToResponse, ok := <-c.send:
			if !ok {
				c.write(websocket.CloseMessage, []byte{})
				return
			}
			if err := c.ws.WriteJSON(threadToResponse); err != nil {
				l.Output(
					logrus.Fields{
						l.ErrMsg:   l.ErrToStr(err),
						l.TraceMsg: l.TraceToStr(l.Trace()),
						"Thread":   l.Sprintf(threadToResponse),
					},
					"can not write JSON",
					l.Debug,
				)
				return
			}
		case <-ticker.C:
			if err := c.write(websocket.PingMessage, []byte{}); err != nil {
				l.PutErr(err, l.Trace(), l.E_R_PingMsg, websocket.PingMessage)
				return
			}
		}
	}
}
// readPump pumps messages from the websocket connection to the hub.
func (c *connection) readPump() {
	defer func() {
		H.Unregister <- c
		c.ws.Close()
	}()
	c.ws.SetReadLimit(maxMessageSize)
	c.ws.SetReadDeadline(time.Now().Add(pongWait))
	c.ws.SetPongHandler(func(string) error { c.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
	for {

		err := c.ws.ReadJSON(&thread)
		if err != nil {
			if thread == nil {
				break
			}
			l.Output(
				logrus.Fields{
					l.ErrMsg:   l.ErrToStr(err),
					l.TraceMsg: l.TraceToStr(l.Trace()),
					"Thread":   l.Sprintf(thread),
				},
				"can not read JSON or Closed Websocket",
				l.Debug,
			)
			break
		}

		if newThread, err = m.UpdateExistingTimeLine(thread); err != nil {
			l.PutErr(err, l.Trace(), l.E_R_Upsert, thread)
		}

		H.Broadcast <- newThread
	}
}