Changeset 428 in code
- Timestamp:
- Nov 24, 2020, 1:13:24 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/downstream.go
r427 r428 288 288 289 289 dc.conn.SendMessage(msg) 290 } 291 292 // sendMessageWithID sends an outgoing message with the specified internal ID. 293 func (dc *downstreamConn) sendMessageWithID(msg *irc.Message, id string) { 294 dc.SendMessage(msg) 295 296 if id == "" || !dc.messageSupportsHistory(msg) { 297 return 298 } 299 300 dc.sendPing(id) 301 } 302 303 // advanceMessageWithID advances history to the specified message ID without 304 // sending a message. This is useful e.g. for self-messages when echo-message 305 // isn't enabled. 306 func (dc *downstreamConn) advanceMessageWithID(msg *irc.Message, id string) { 307 if id == "" || !dc.messageSupportsHistory(msg) { 308 return 309 } 310 311 dc.sendPing(id) 312 } 313 314 // ackMsgID acknowledges that a message has been received. 315 func (dc *downstreamConn) ackMsgID(id string) { 316 netName, entity, _, _, err := parseMsgID(id) 317 if err != nil { 318 dc.logger.Printf("failed to ACK message ID %q: %v", id, err) 319 return 320 } 321 322 network := dc.user.getNetwork(netName) 323 if network == nil { 324 return 325 } 326 327 history, ok := network.history[entity] 328 if !ok { 329 return 330 } 331 332 history.clients[dc.clientName] = id 333 } 334 335 func (dc *downstreamConn) sendPing(msgID string) { 336 token := "soju-msgid-" + base64.RawURLEncoding.EncodeToString([]byte(msgID)) 337 dc.SendMessage(&irc.Message{ 338 Command: "PING", 339 Params: []string{token}, 340 }) 341 } 342 343 func (dc *downstreamConn) handlePong(token string) { 344 if !strings.HasPrefix(token, "soju-msgid-") { 345 dc.logger.Printf("received unrecognized PONG token %q", token) 346 return 347 } 348 token = strings.TrimPrefix(token, "soju-msgid-") 349 b, err := base64.RawURLEncoding.DecodeString(token) 350 if err != nil { 351 dc.logger.Printf("received malformed PONG token: %v", err) 352 return 353 } 354 msgID := string(b) 355 356 dc.ackMsgID(msgID) 290 357 } 291 358 … … 876 943 } 877 944 945 // messageSupportsHistory checks whether the provided message can be sent as 946 // part of an history batch. 947 func (dc *downstreamConn) messageSupportsHistory(msg *irc.Message) bool { 948 // Don't replay all messages, because that would mess up client 949 // state. For instance we just sent the list of users, sending 950 // PART messages for one of these users would be incorrect. 951 // TODO: add support for draft/event-playback 952 switch msg.Command { 953 case "PRIVMSG", "NOTICE": 954 return true 955 } 956 return false 957 } 958 878 959 func (dc *downstreamConn) sendNetworkHistory(net *network) { 879 960 if dc.caps["draft/chathistory"] || dc.user.msgStore == nil { … … 907 988 908 989 for _, msg := range history { 909 // Don't replay all messages, because that would mess up client 910 // state. For instance we just sent the list of users, sending 911 // PART messages for one of these users would be incorrect. 912 ignore := true 913 switch msg.Command { 914 case "PRIVMSG", "NOTICE": 915 ignore = false 916 } 917 if ignore { 990 if !dc.messageSupportsHistory(msg) { 918 991 continue 919 992 } … … 984 1057 }) 985 1058 return nil 1059 case "PONG": 1060 if len(msg.Params) == 0 { 1061 return newNeedMoreParamsError(msg.Command) 1062 } 1063 token := msg.Params[len(msg.Params)-1] 1064 dc.handlePong(token) 986 1065 case "USER": 987 1066 return ircError{&irc.Message{ -
trunk/upstream.go
r423 r428 1608 1608 } 1609 1609 1610 func (uc *upstreamConn) appendLog(entity string, msg *irc.Message) { 1610 // appendLog appends a message to the log file. 1611 // 1612 // The internal message ID is returned. If the message isn't recorded in the 1613 // log file, an empty string is returned. 1614 func (uc *upstreamConn) appendLog(entity string, msg *irc.Message) (msgID string) { 1611 1615 if uc.user.msgStore == nil { 1612 return 1616 return "" 1613 1617 } 1614 1618 … … 1623 1627 if err != nil { 1624 1628 uc.logger.Printf("failed to log message: failed to get last message ID: %v", err) 1625 return 1629 return "" 1626 1630 } 1627 1631 … … 1647 1651 if err != nil { 1648 1652 uc.logger.Printf("failed to log message: %v", err) 1649 return 1650 } 1651 1652 if !detached && msgID != "" { 1653 uc.forEachDownstream(func(dc *downstreamConn) { 1654 history.clients[dc.clientName] = msgID 1655 }) 1656 } 1653 return "" 1654 } 1655 1656 return msgID 1657 1657 } 1658 1658 … … 1663 1663 // forwarded to all connections except origin. 1664 1664 func (uc *upstreamConn) produce(target string, msg *irc.Message, origin *downstreamConn) { 1665 var msgID string 1665 1666 if target != "" { 1666 uc.appendLog(target, msg)1667 msgID = uc.appendLog(target, msg) 1667 1668 } 1668 1669 … … 1674 1675 uc.forEachDownstream(func(dc *downstreamConn) { 1675 1676 if dc != origin || dc.caps["echo-message"] { 1676 dc.SendMessage(dc.marshalMessage(msg, uc.network)) 1677 dc.sendMessageWithID(dc.marshalMessage(msg, uc.network), msgID) 1678 } else { 1679 dc.advanceMessageWithID(msg, msgID) 1677 1680 } 1678 1681 })
Note:
See TracChangeset
for help on using the changeset viewer.