PubNub Live Chat Beta Testing


Login or Register for Dates, Times and to Reply

 
Thread Tools Search this Thread
# 36  
When I was watching the network requests earlier today, I thought I saw a reference to PubNub JavaScript v4.20.? and then later saw 4.23.0. I check the server logs and see that wasn't the case, my mistake.

Interestingly enough, I did see 91 requests that came from JS v3.16.3.
This User Gave Thanks to pubnubcraig For This Post:
# 37  
Hi Craig,

Here is the pubnub dependency in the node project:

Code:
 "pubnub": "^4.23.0",

The PHP version of the SDK (used for server side messages) was provided to me by your team, and of course that it is a different project and I don't have that information handy.

I have no idea why the pubnode SDK has tokens that shows JS v3.16.3, but I just started this project a few weeks ago and only installed "pubnub": "^4.23.0",

I assume there is legacy code in your SDK and that is why you are setting what you are seeing.

I did install "pubnub-vue": "^1.0.1", initially, but I abandoned that code rather quickly. I probably should remove the that unused package from my project file, which I just did:

Code:
npm uninstall pubnub-vue --save

and rebuilt the project without this unused code in version 0.7604, which I just built and installed on the server.

Maybe removing that pubnub-vue repo, which I thought was unused, will get rid of the JS v3.16.3 code you were seeing?

Also, when I have time, I'll rebuild the project and test:

Code:
  pubnub.subscribe({
      channels: ["ch1", "control"],
      withPresence: true
    });

right now, it is still running:

Code:
  pubnub.subscribe({
      channels: ["ch1", "control"],
      withPresence: false
    });



I will test this again soon, with the changes you made to our pubnub config and report back!

Thanks for all your great help and interest in this little project
# 38  
UserCP Screeching Frog 0.7605

pubnubcraig's changes on the backend have really helped out.

Thanks Craig!!
  • Set pubnub.subscribe( withPresence: true });
  • Removed all getHereNow() calls except on the initial page created(), as Craig suggested (demanded Smilie )
  • Wrote new code in the Listener() in the presence object.

It seems to work as expected now, with the exception of sometimes the user does not see "himself" as a participant in the live chat. I need to figure that small bug out.

Here is the core version v0.7605 Vue.js code:

Code:
<template>
  <div class="bottomfill">
    <div class="d-flex justify-content-start flex-wrap room nomargin togglearea">
      <div class="checkbox leftmargin">
        <label>
          <input class="ckbox" type="checkbox" v-model="reverseorder">
          <span v-bind:class="{reverseon: this.reverseorder}" class="toggler">Toggle Message Order</span>
          <span v-if="this.reverseorder">
            <i v-bind:class="{reverseon: this.reverseorder}" class="tim-icons icon-minimal-down"></i>
          </span>
          <span v-else>
            <i class="tim-icons icon-minimal-up"></i>
          </span>
        </label>
      </div>
    </div>

    <div class="d-flex justify-content-around flex-wrap room">
      <div class="col-md-12 box">
        <div
          class="neo-chat-title"
          v-if="this.psoccupancy"
        >Live Chat Participants: {{ this.psoccupancy}}</div>

        <div class="neo-chat-title">{{ this.userlist}}</div>
        <VueSteamChat :messages="this.msglist" @vue-steam-chat-on-message="onNewMessage"/>
      </div>
    </div>

    <div class="d-flex justify-content-around flex-wrap room channelbar">
      <div>Channels</div>
      <div class="checkbox">
        <label>
          <input class="ckbox" type="checkbox" v-model="livebox">
          <span v-bind:class="{liveon: this.livebox}">Live</span>
        </label>
      </div>
      <div class="checkbox">
        <label>
          <input class="ckbox" type="checkbox" v-model="postsbox">
          <span v-bind:class="{liveon: this.postsbox}">Posts</span>
        </label>
      </div>
      <div class="checkbox disabled">
        <label>
          <input class="ckbox" type="checkbox" v-model="statusbox">
          <span v-bind:class="{liveon: this.statusbox}">Status</span>
        </label>
      </div>
    </div>
  </div>
</template>

<script>
function init() {
  sessionStorage.setItem("loaded", true);
}
window.onload = init;
var _ = require("lodash");
import Vue from "vue";
import VueSteamChat from "vue-steam-chat";
import { setTimeout, setInterval, clearInterval } from "timers";
var PubNub = require("pubnub");
require("vue-steam-chat/dist/index.css");
var interval = null;
var vbchat = "";

if (window.vbname == "Unregistered") {
  const d = Math.floor(Math.random() * 100);
  if (localStorage.getItem("randomuser")) {
    vbchat = "Guest " + localStorage.getItem("randomuser");
  } else {
    const d = Math.floor(Math.random() * 100);
    localStorage.setItem("randomuser", d);
    vbchat = "Guest " + localStorage.getItem("randomuser");
  }
} else {
  vbchat = window.vbname;
}

var pubnub = new PubNub({
  subscribeKey: "demo",
  publishKey: "demo",
  ssl: true,
  keepAlive: true,
  // heartbeatInterval: 10,
  presenceTimeout: 300,
  restore: true,
  uuid: vbchat
});

export default {
  name: "vue-steam-chat",
  components: {
    VueSteamChat
  },
  computed: {
    msglist() {
      var listarray = [];
      //console.log("this.text ", this.text);
      var that = this;
      this.text.forEach(function(element) {
        if (
          element.text.match(/Forum Replied To/g) ||
          element.text.match(/Forum Started Post/g)
        ) {
          if (that.postsbox == true) {
            listarray.push(element);
          }
        } else if (element.text.match(/Forum Status/g)) {
          if (that.statusbox == true) {
            listarray.push(element);
          }
        } else if (that.livebox == true) {
          listarray.push(element);
        }
      });
      if (this.reverseorder == true) {
        return listarray.reverse();
      } else {
        return listarray;
      }
      //this.adjustScroll();
    },
    uuid() {
      return pubnub.getUUID();
    }
  },
  data() {
    return {
      updateCount: 0,
      blockpublish: false,
      livebox: true,
      reverseorder: true,
      postsbox: true,
      statusbox: true,
      historydone: false,
      userlist: "",
      userarray: [],
      uuida: window.vbuserId,
      uuname: window.vbusername,
      ch1: null,
      time: Date.now() / 1000,
      chathist: [],
      laststatuschange: [{}],
      occupancy: 0,
      psoccupancy: 0,
      initdone: 0,
      status: 0,
      text: [
        {
          time: 1506117496,
          username: "Gaben",
          text: "Chat initialized ..."
        },
        {
          time: 1506117500,
          username: "Solo",
          text: "So, say something !!"
        },
        {
          time: 1506117530,
          username: "Neo",
          text: "Hmmm ..."
        }
      ]
    };
  },
  methods: {
    adjustScroll() {
      var scroll = document.querySelector(".vue-steam-chat__wrapper--scroll");
      var view = document.querySelector(".bottomfill");

      if (!this.reverseorder) {
        scroll.scrollTop = 0;
        view.scrollIntoView({
          behavior: "smooth",
          block: "start",
          inline: "nearest"
        });
      } else {
        scroll.scrollTop = scroll.scrollHeight;
        channels.scrollIntoView({
          behavior: "smooth",
          block: "end",
          inline: "nearest"
        });
      }
    },
    initScroll() {
        var view = document.querySelector(".bottomfill");
        behavior: "smooth",
        block: "end",
        inline: "nearest"
      });
    },
    getHereNow() {
      var that = this;
      pubnub.hereNow(
        {
          channels: ["ch1"],
          // channelGroups : ["cg1"],
          includeUUIDs: true,
          includeState: true
        },
        function(status, response) {
          if (response.totalOccupancy == 0) {
            that.psoccupancy = 1;
            var allusers = "";
          } else {
            that.psoccupancy = response.totalOccupancy;
            var allusers = "";
          }
          // console.log("herenow: ", response);

          var index = 0;

          response.channels.ch1.occupants.forEach(function(user) {
            if (response.channels.ch1.occupants) {
              that.userarray.push(user);
              if (index == 0) allusers = user.uuid;
              else allusers = allusers + ", " + user.uuid;
            }
            index++;
            that.userlist = allusers;
          });
        }
      );
    },
    history() {
      var that = this;
      if (pubnub) {
        pubnub.history(
          {
            reverse: false,
            channel: "ch1",
            count: 100, // how many items to fetch
            stringifiedTimeToken: true // false is the default
          },
          function(status, response) {
            if (status.error == false) {
              response.messages.forEach(function(element) {
                if (element.entry.username && element.entry.text != undefined) {
                  if (
                    element.entry.text.match(/Forum Replied To/g) ||
                    element.entry.text.match(/Forum Started Post/g)
                  ) {
                    if (that.postsbox == true) {
                      that.text.push(element.entry);
                    }
                  } else if (element.entry.text.match(/Forum Status/g)) {
                    if (that.statusbox == true) {
                      that.text.push(element.entry);
                    }
                  } else if (that.livebox == true) {
                    that.text.push(element.entry);
                  }
                }
              });
              that.historydone = true;
            } else {
              console.log("error ", status);
            }
          }
        );
      }
      that.initScroll();
    },
    controlMessage(message) {
      var that = this;
      if (message.length < 2) {
        return false;
      }
      let m = {
        time: Date.now() / 1000,
        username: this.uuid,
        text: message
      };
      var publishConfig = {
        sendByPost: true,
        channel: "controlreply",
        message: m
      };

      pubnub.publish(publishConfig, function(status, response) {
        if (status.error) {
          console.log(status);
        } else {
          // console.log("control message Published w/ timetoken", JSON.stringify(publishConfig));
        }
      });
    },

    onNewMessage(message) {
      var that = this;
      if (message.length < 2) {
        return false;
      }
      let m = {
        time: Date.now() / 1000,
        username: this.uuid,
        text: message
      };
      var publishConfig = {
        sendByPost: true,
        channel: "ch1",
        message: m
      };

      if (that.blockpublish != true) {
        pubnub.publish(publishConfig, function(status, response) {
          if (status.error) {
            console.log(status);
          } else {
            // console.log("message Published w/ timetoken", response.timetoken);
          }
        });
      }
    }
  },
  created() {
    $.LoadingOverlay("show");
    pubnub.subscribe({
      channels: ["ch1", "control"],
      withPresence: true
    });
  },
  updated() {
    this.adjustScroll();
  },
  beforeDestroy() {
    pubnub.unsubscribe({
      channels: ["ch1", "control"]
    });
    var existingListener = {
      message: function() {}
    };

    if (existingListener) pubnub.removeListener(existingListener);
    if (interval) {
      clearInterval(interval);
    }
  },
  async mounted() {
    if (localStorage.blc) {
      if (localStorage.getItem("blc") == "true") {
        this.blockpublish = true;
      }
    }
    if (localStorage.status_msgs) {
      if (localStorage.getItem("status_msgs") == "yes") {
        this.statusbox = true;
      }
    }
    var that = this;
    that.history();
    that.getHereNow();
    pubnub.addListener({
  
      message: function(m) {
        // console.log("livechat msg channel received: ", JSON.stringify(m));
        that.adjustScroll();
        if (m.channel == "ch1") {
          if (
            m.message.text.match(/Forum Replied To/g) ||
            m.message.text.match(/Forum Started Post/g)
          ) {
            if (that.postsbox == true) {
              that.text.push(m.message);
            }
          } else if (m.message.text.match(/Forum Status/g)) {
            if (that.statusbox == true) {
              that.text.push(element.entry);
            }
          } else if (that.livebox == true) {
            that.text.push(m.message);
          }
        } else if (m.channel == "control") {
          if (m.message.text.match(/ping/gi)) {
            that.controlMessage(
              "IAMHERE V" +
                that.$store.state.version.toFixed(4) +
                " Blocked: " +
                that.blockpublish
            );
          }
          //   console.log("live chat control", m.channel, m.message);
         //
         // removed internal control code
        //
      }
      },
      presence: function(presenceEvent) {
        that.psoccupancy = presenceEvent.occupancy;
        //const i = Date.now();
        //console.log("listen presence", presenceEvent);
        if (presenceEvent.channel == "ch1") {
          if (presenceEvent.action == "join") {
            var rawarray = that.userlist.split(",");
            var arr = _.remove(rawarray, function(n) {
              return n.length > 2;
            });
            arr.push(presenceEvent.uuid);
            that.userlist = arr.join(", ");
            //that.userlist.replace(/^,/, "");
            //console.log("listen presence join", that.userlist);
          } else if (presenceEvent.action == "leave") {
            var arr = that.userlist.split(",");
            var trimmed = [];
            arr.forEach(element => {
              trimmed.push(element.trim());
            });

            var removed = _.remove(trimmed, function(n) {
              return n != presenceEvent.uuid.trim();
            });
            var newarr = removed.join(",");
            that.userlist = newarr;
            // console.log("listen presence leave", newarr);
          }
        }
      }
    });
    var mythis = this;
    $(function() {
      var input = document.querySelector(".vue-steam-chat__textarea");
      var button = document.querySelector(".vue-steam-chat__button");
      var scroll = document.querySelector(".vue-steam-chat__wrapper--scroll");
      input.addEventListener("keyup", function(event) {
        if (event.keyCode === 13) {
          event.preventDefault();
          button.click();
        }
      });
      $.LoadingOverlay("hide");
    });
  }
};
</script>
<style scoped>
.box {
  margin: 0px !important;
  height: 500px;
  margin: 20px;
}

.neo-chat-title {
  color: slategray;
  font-size: 1.2em;
  text-align: center;
  margin: 10px;
}

.room {
  margin-bottom: 20px;
}

.ckbox {
  margin-right: 7px;
  background-color: cornflowerblue;
}

.reverseon,
.liveon,
.ckbox {
  color: cornflowerblue;
}

.nomargin {
  margin: 0px 0px 0px 0px;
}

.leftmargin {
  margin-left: 30px;
}

.toggler {
  margin: 10px 10px 0px 0px;
}

.channelbar {
  margin: 100px 10px 10px 10px;
  padding-bottom: 10px;
}

.bottomfill {
  margin-bottom: 0px;
  padding-top: 20px;
}
</style>

# 39  
Mystery solved - I dug in further to the logs to find out the source of the v3 SDK. I was our Realtime Analytics tool that you must have enabled at one time. It hasn't been upgraded because it still works on that older version, but likely we will be EOL'ing/removing that tool in the next release of the PubNub Admin Dashboard.
This User Gave Thanks to pubnubcraig For This Post:
# 40  
Well, considering PubNub supported countless SDKs and features, it's hard to keep track of all the changes in a face paced world!

Thanks for following up, Craig.

PubNub is great stuff and slowing I'm learning more and more how the SDK works; but I have a long way to go.
# 41  
Thanks Neo - I am continually impressed and amazed at the ability of our engineering team to maintain so much technology and continue to innovate. Keep pushing us on where we do not measure up and we'll continue to address those issues.
#developers
# 42  
UserCP Screeching Frog 0.7607
  • Solved race condition when page is first mounted() by delaying getHereNow() by 3 seconds.

Could have been 2 to 5 seconds, so I compromised at 3 seconds:

Code:
async mounted() {
    setTimeout(this.getHereNow, 3000);
   // ...
}

Hey Craig,

What's the best way to keep the user's chat session alive (from a presence perspective) when they are just lurking and watching but not interacting?

Do I just set the initial presenceTimeout > 300, say 600 or maybe even 1200 seconds?
Login or Register for Dates, Times and to Reply

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

3 More Discussions You Might Find Interesting

1. What is on Your Mind?

Live Chat (Alpha) in UserCP SF 0.7517

Interesting.... I am still working on the kinks for Live Chat here at unix.com using a publish-subscribe API from PubNub. Two days ago while working on it, a new user joined the live chat and asked about how to post a new thread in the forum. Then today, one of the members of the PubNub team... (22 Replies)
Discussion started by: Neo
22 Replies

2. What is on Your Mind?

A Quick Video Overview of PubNub Live Chat @UNIX.com (version 0.7614)

A number of people have asked me to make some videos, so I just got my first condenser microphone and so I can make some amateurish screen casts. I will try to do better in the future. A quick overview of PubNub Live Chat @unix.com The video is best is you set the Quality to HD 1080. The... (0 Replies)
Discussion started by: Neo
0 Replies

3. Solaris

Live Chat For Solaris?

Does anyone know of any online live chat discussion groups for Solaris? If so, please let me know... Thanks! Rob Sandifer (3 Replies)
Discussion started by: RobSand
3 Replies

Featured Tech Videos