【问题标题】:Coldfusion Websockets "User is typing..." FunctionalityColdfusion Websockets“用户正在输入......”功能
【发布时间】:2013-05-27 17:21:45
【问题描述】:

我正在使用 Coldfusion 10 的 websockets 并进行了简单的聊天以进行测试。我见过几个聊天,他们有“用户正在输入...”文本,当其他用户正在输入时出现。有谁知道如何有效地实现这一点?

【问题讨论】:

    标签: javascript coldfusion websocket coldfusion-10 cfwebsocket


    【解决方案1】:

    再创建一个频道“通知”并在用户执行“keyDown”时发布“用户正在输入”,在“keyUp”时发布“空字符串”。

    订阅此频道与您聊天。接收方此通道的目标应是其内部 html 可以填充“用户正在键入”消息。

    伪代码:

    <cfwebsocket name="notificationSocket" 
                 onmessage="notifyHandler"
                 subscribeto="notificationChannel" >
    
    <cfwebsocket name="ChatSocket" 
                 onmessage="chatHandler"
                 subscribeto="chatChannel" >
    
    <!-- Conversation displayer -->
    <div id="messageBoard"></div>
    
    <!-- your text message input area -->
    <textarea onKeyDown="sayTyping()" onKeyUp="sayStopped()" id="chatInput"></textarea>
    <div id="notifyArea"></div>
    <input name="submit" onClick="publishMessage()"></textarea>
    
    <script>
    
        /*chat Functions*/
        var publishMessage = function(){
            var msg = document.getElementById('chatInput').value;
            mycfwebsocketobject.publish("chatChannel", msg );
        };
    
        var chatHandler = function(msgObj){
            document.getElementById('messageBoard').innerHTML += ColdFusion.JSON.encode(msgObj);
        };
    
    
        /*notifying Functions*/
        var notifyHandler = function(noteObj){
            document.getElementById('notifyArea').innerHTML = ColdFusion.JSON.encode(noteObj);
        };    
    
        var sayTyping = function(){
            mycfwebsocketobject.publish("notificationchannel","User is Typing..." );
        };
        var sayStopped = function(){
            mycfwebsocketobject.publish("notificationchannel","" );
        };
    
    </script>
    

    另一个增强功能是让 div 已经包含文本“用户正在输入”,并且您的频道将文本广播为“显示”和“不显示”。这基本上是赋予 显示和隐藏它的类名。流量减少。

    方法 2使用相同的渠道

    <cfwebsocket name="ChatSocket" 
                 onmessage="chatHandler"
                 subscribeto="chatChannel" >
    
    <!-- Conversation displayer -->
    <div id="messageBoard"></div>
    
    <!-- your text message input area -->
    <textarea onKeyDown="sayTyping()" onKeyUp="sayStopped()" id="chatInput"></textarea>
    <div id="notifyArea" class="no">User is typing...</div>
    <input name="submit" onClick="publishMessage()"></textarea>
    
    <script>
    
        /*chat Functions*/
        var publishMessage = function(){
            var msg = document.getElementById('chatInput').value;
            mycfwebsocketobject.publish("chatChannel", msg );
        };
    
        var chatHandler = function(msgObj){
            var msg = ColdFusion.JSON.encode(msgObj);
            if (msg == '@userTyping@-yes'){
                notifyHandler('yes');
            }
            else if (msg == '@userTyping@-no'){
                notifyHandler('no');
            }
            else {
                document.getElementById('messageBoard').innerHTML += msg;
            }
        };
    
    
        /*notifying Functions*/
        var notifyHandler = function(action){
    
            document.getElementById('notifyArea').className = action;
    
            /*call the notify handler with off to stop showing the user is typing message
            after a certain interval of time. This is to avoid someone believing that 
            partner is still typing even when the connection is lost*/
    
            if(action == 'on'){
                setTimeout(function(){notifyHandler('no')},250);
            }
        };    
    
        var sayTyping = function(){
            mycfwebsocketobject.publish("chatChannel","@userTyping@-yes" );
        };
        var sayStopped = function(){
            mycfwebsocketobject.publish("chatChannel","@userTyping@-no" );
        };
    
    </script>
    <style>
    .yes { display:block;}
    .no { display:none;}
    </style>
    

    人们总是可以通过将消息键入“@userTyping@-yes”或“@userTyping@-no”来欺骗此代码。但正如我所说,这只是一个 POC。此外,对于您提到的超时,keyUp 无论如何都会处理它。但是您也可以通过 setTimeout() 调用 notifyHandler(),如上所示。

    【讨论】:

    • 感谢您的示例。唯一的问题是我正在使用 websocket 进行实时帮助聊天,因此对话将是一对一的,而不是向频道中的每个人广播。我是否需要为每个发起的聊天创建一个唯一的 notificationSocket 子频道?另外,是否应该有一个超时,这样它就不会不断更新每个按下的键?
    • 在这种情况下,您可以使用相同的渠道并调整您的逻辑来区分传入消息是“通知”还是聊天消息。
    • 因此,进行一对一聊天(例如实时帮助聊天)的最佳方式是拥有一个频道并按 ID 过滤?
    • 您可以这样做,或者最好的方法是使用用户会话 ID 进行过滤。从 BenNadel 博客阅读这篇精彩的文章 - bennadel.com/blog/…。它更像是一个分步指南。
    【解决方案2】:

    评论内有一个关于如何过滤一对一消息的问题。下面是一些实现这一点的示例代码。

    不使用subscribeTo属性,而是使用js函数订阅用户并传入一些头部值。然后可以使用selector 将这些标头用作发布调用的过滤器

    例子:

    <cfwebsocket name="ChatSocket" onOpen="openHandler" onMessage="msgHandler" onError="errHandler">
    
    <script>
        function openHandler(){
            //Subscribe to the channel, pass in headers for filtering later
            ChatSocket.subscribe('chatChannel',{name: '#Session.Auth.FirstName#', UserID: '#Session.Auth.UserID#', AccountID: '#Session.Auth.AccountID#' });
        }
    
        function publish(txt, userID){
            var msg = {
                AccountID: "#Session.Auth.AccountID#",
                publisher: '#Session.Auth.UserID#', 
                id: userID,
                message: converthtml(txt)
            };
            //When including headers, the "selector" is where you will filter who it goes to.
            var headers = {
                AccountID: "#Session.Auth.AccountID#",
                publisher: '#Session.Auth.UserID#', 
                id: userID,
                selector: "UserID eq '"+userID+"' and AccountID eq '#Session.Auth.AccountID#'"
            };
            ChatSocket.publish('chatChannel',msg, headers);
    
        }
    
        function msgHandler(message){
            console.log(message);
        }
    
        function errHandler(err){
            console.log(err);
        }
    </script>
    

    【讨论】:

      猜你喜欢
      • 2011-05-24
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-03
      • 1970-01-01
      • 2017-09-18
      相关资源
      最近更新 更多