Coldfusion Websockets "用户正在输入…功能

Coldfusion Websockets "User is typing..." Functionality

本文关键字:输入 功能 用户 Websockets quot Coldfusion      更新时间:2023-09-26

我正在玩Coldfusion 10的websockets,并做了一个简单的聊天测试。我见过一些聊天,他们有"用户正在打字……"的文本,显示当其他用户正在打字。有人知道如何有效地实现这一点吗?

创建另一个通道'通知'并在其中发布'用户正在键入'当用户执行'keyDown'和'keyUp'时'emptystring'

订阅这个频道和你一起聊天。接收端此通道的目标应该是一个,其内部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已经与文本"用户正在打字"和你的频道广播文本为"show"answers"noshow"。这基本上是给定的类名,用于显示和隐藏它。减少交通。

方法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(),如上所示。

Comments内部是一个关于如何过滤一对一消息传递的问题。下面是实现这个目标的一些示例代码。

不使用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>