Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions experiments/test_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python3
"""Simple HTTP server for testing HTML files locally"""
import http.server
import socketserver
import sys

PORT = 8000

class MyHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
# Add CORS headers for WebSocket testing
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET')
self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate')
super().end_headers()

if __name__ == "__main__":
Handler = MyHTTPRequestHandler

with socketserver.TCPServer(("", PORT), Handler) as httpd:
print(f"Server running at http://localhost:{PORT}/")
print(f"Test index.html at: http://localhost:{PORT}/index.html")
print(f"Test messages.html at: http://localhost:{PORT}/messages.html")
print("Press Ctrl+C to stop")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("\nServer stopped.")
sys.exit(0)
45 changes: 45 additions & 0 deletions experiments/test_websocket.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebSocket Test</title>
<style>
body { font-family: monospace; padding: 20px; background: #000; color: #0F0; }
#messages { white-space: pre-wrap; }
</style>
</head>
<body>
<h1>WebSocket Test - Quixio AI Chat Stream</h1>
<div id="status">Connecting...</div>
<div id="messages"></div>

<script>
const statusEl = document.getElementById('status');
const messagesEl = document.getElementById('messages');

const ws = new WebSocket('wss://ai-chat-wss-demo-realtimedatasources-prod.deployments.quix.io/timeseries');

ws.onopen = function() {
statusEl.textContent = 'Connected!';
statusEl.style.color = '#0F0';
};

ws.onmessage = function(event) {
const data = JSON.parse(event.data);
messagesEl.textContent += JSON.stringify(data, null, 2) + '\n\n';
console.log('Received:', data);
};

ws.onerror = function(error) {
statusEl.textContent = 'Error: ' + error;
statusEl.style.color = '#F00';
console.error('WebSocket error:', error);
};

ws.onclose = function() {
statusEl.textContent = 'Disconnected';
statusEl.style.color = '#F80';
};
</script>
</body>
</html>
82 changes: 56 additions & 26 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

<head>
<meta charset="utf-8">
<script src="https://cdn.pubnub.com/pubnub.min.js"></script>
<script src="unistring.js"></script>
<script src="symbols.js"></script>
<title>Twitter Matrix</title>
Expand All @@ -30,9 +29,9 @@
<script>
// based on
// https://codepen.io/P3R0/pen/MwgoKv
// https://www.pubnub.com/developers/realtime-data-streams/twitter-stream/
var twitterMessage = "";
// Real-time data stream from https://github.com/quixio/real-time-data-sources

var chatMessage = "";
var alphabet = ["0", "1"];
var offset = 0;

Expand Down Expand Up @@ -66,17 +65,17 @@
for (var i = 0; i < drops.length; i++) {
//a random alphabet character to print
//var text = alphabet[Math.floor(Math.random() * alphabet.length)];

console.log(offset);

if (offset >= alphabet.length)
offset = 0;

var text = alphabet[offset++];

if (!text)
text = " ";

//x = i*font_size, y = value of drops[i]*font_size
ctx.fillText(text, (i * font_size) + (font_size / 2), drops[i] * font_size);
//ctx.fillText(letters.length.toString(), font_size, font_size);
Expand All @@ -92,24 +91,55 @@
}

setInterval(draw, 44);

PUBNUB.init({
subscribe_key: 'sub-c-78806dd4-42a6-11e4-aed8-02ee2ddab7fe',
ssl: true
}).subscribe({
channel: 'pubnub-twitter',
message: function(msg) {
twitterMessage = msg.text;

var letters = getSymbols(twitterMessage);

if (alphabet.length >= 10240)
alphabet = alphabet.slice(alphabet.length - letters.length);

for (var i = 0; i < letters.length; i++)
alphabet.push(letters[i]);

// Connect to WebSocket stream for real-time chat data
var ws = new WebSocket('wss://ai-chat-wss-demo-realtimedatasources-prod.deployments.quix.io/timeseries');

ws.onopen = function() {
console.log('Connected to real-time data stream');
};

ws.onmessage = function(event) {
try {
var data = JSON.parse(event.data);

// Extract chat text from the WebSocket message
// The data format includes timestamps and parameters with chat text
if (data.timestamps && data.timestamps.length > 0) {
// Look for the 'chat' parameter in the data
if (data.stringValues && data.stringValues.chat) {
for (var i = 0; i < data.stringValues.chat.length; i++) {
var text = data.stringValues.chat[i];
if (text && text.length > 0) {
chatMessage = text;

var letters = getSymbols(chatMessage);

if (alphabet.length >= 10240)
alphabet = alphabet.slice(alphabet.length - letters.length);

for (var j = 0; j < letters.length; j++)
alphabet.push(letters[j]);
}
}
}
}
} catch (e) {
console.error('Error parsing message:', e);
}
});
};

ws.onerror = function(error) {
console.error('WebSocket error:', error);
};

ws.onclose = function() {
console.log('Disconnected from stream, attempting to reconnect...');
// Attempt to reconnect after 5 seconds
setTimeout(function() {
location.reload();
}, 5000);
};
</script>
</body>

Expand Down
84 changes: 56 additions & 28 deletions messages.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">

<script src="https://cdn.pubnub.com/pubnub.min.js"></script>
<script src="unistring.js"></script>
<script src="symbols.js"></script>
<title>Twitter Matrix</title>
Expand All @@ -33,7 +32,7 @@
onload = function() {
// based on
// https://codepen.io/P3R0/pen/MwgoKv
// https://www.pubnub.com/developers/realtime-data-streams/twitter-stream/
// Real-time data stream from https://github.com/quixio/real-time-data-sources

// visualization settings
var maxMessages = 10240;
Expand All @@ -47,7 +46,7 @@

var maxStepsToResetColumn = 200;

var twitterMessages = []; // data stack (queue)
var chatMessages = []; // data stack (queue)
var messages = []; // current printed data

var a = document.getElementById("a");
Expand Down Expand Up @@ -187,12 +186,12 @@
else
{
var startNewColumn = Math.random() > 0.95;
if (twitterMessages.length > 0 && startNewColumn)
if (chatMessages.length > 0 && startNewColumn)
{
var twitterMessage = twitterMessages.pop();
var symbols = getSymbols(twitterMessage.text);
message.url = twitterMessage.url;
var chatMessage = chatMessages.pop();
var symbols = getSymbols(chatMessage.text);

message.url = chatMessage.url;
message.offset = 0;
message.symbols = symbols;
}
Expand All @@ -206,22 +205,22 @@
}

// adjust speed
if (twitterMessages.length > (columns * 2))
if (chatMessages.length > (columns * 2))
{
if (currentSpeed > minSpeed)
{
currentSpeed -= speedStep; // speed up

clearInterval(timerId);
timerId = setInterval(draw, currentSpeed);
}
}
else if (twitterMessages.length < (columns / 2))
else if (chatMessages.length < (columns / 2))
{
if (currentSpeed < maxSpeed)
{
currentSpeed += speedStep; // slow down

clearInterval(timerId);
timerId = setInterval(draw, currentSpeed);
}
Expand All @@ -231,27 +230,56 @@
// Take language from url hash parameter
language = window.location.hash.substr(1).toLowerCase();

function addTwitterMessage(msg) {
var messageUrl = "https://twitter.com/" + msg.user.screen_name + "/status/" + msg.id_str;
twitterMessages.push({ text: msg.text, url: messageUrl });
function addChatMessage(text, conversationId) {
// Create a simple URL (no actual link available for chat messages)
var messageUrl = "#" + conversationId;
chatMessages.push({ text: text, url: messageUrl });
}

PUBNUB.init({
subscribe_key: 'sub-c-78806dd4-42a6-11e4-aed8-02ee2ddab7fe',
ssl: true
}).subscribe({
channel: 'pubnub-twitter',
message: function(msg) {
// skip if there are too many messages (events)
if (twitterMessages.length < maxMessages)
{
if (!language || msg.lang == language)
{
addTwitterMessage(msg);
// Connect to WebSocket stream for real-time chat data
var ws = new WebSocket('wss://ai-chat-wss-demo-realtimedatasources-prod.deployments.quix.io/timeseries');

ws.onopen = function() {
console.log('Connected to real-time data stream');
};

ws.onmessage = function(event) {
try {
var data = JSON.parse(event.data);

// Extract chat text from the WebSocket message
// The data format includes timestamps and parameters with chat text
if (data.timestamps && data.timestamps.length > 0) {
// Look for the 'chat' parameter in the data
if (data.stringValues && data.stringValues.chat) {
var conversationId = data.stringValues.conversation_id ? data.stringValues.conversation_id[0] : 'unknown';
for (var i = 0; i < data.stringValues.chat.length; i++) {
var text = data.stringValues.chat[i];
if (text && text.length > 0) {
// skip if there are too many messages (events)
if (chatMessages.length < maxMessages) {
addChatMessage(text, conversationId);
}
}
}
}
}
} catch (e) {
console.error('Error parsing message:', e);
}
});
};

ws.onerror = function(error) {
console.error('WebSocket error:', error);
};

ws.onclose = function() {
console.log('Disconnected from stream, attempting to reconnect...');
// Attempt to reconnect after 5 seconds
setTimeout(function() {
location.reload();
}, 5000);
};

}
</script>
Expand Down