sub.unsubscribe do not delete channels, how can I delete channels alternatively?
I tried channel.close() or channel.quit() but that didn't work!
Code:
let roomChannelName = room_${roomId}_server;
let sub = redis.createClient(redisConfig);
const channel = this.scServer.exchange.channel(roomChannelName);
sub.unsubscribe(roomChannelName);
this.scServer.exchange.destroyChannel(roomChannelName)
You CANNOT delete a channel manually.
If there's no client subscribes to a channel, Redis will delete the channel automatically.
sub.unsubscribe(roomChannelName);
this.scServer.exchange.destroyChannel(roomChannelName)
I'm a little unclear which library this is, but: "destroy channel" isn't a concept in redis. A channel is active as long as one or more connections exist that are listening to it (via subscribe or psubscribe). It doesn't "exist" in any other semantic sense - it doesn't need to be declared ahead of time, nor does it need to be destroyed. If you want to see whether a channel has listeners, you can use either:
pubsub numsub {channel name}
or, if you don't mind sending dummy data - just publish to it:
publish {channel name} {dummy value}
either of these will return the count of subscribers for the channel:
127.0.0.1:6379> pubsub numsub foo
1) "foo"
2) (integer) 0
127.0.0.1:6379> publish foo bar
(integer) 0
I don't know if your library has an API to expose this, but ultimately: you don't have to do anything here. You don't need to clean up after yourself with pub/sub.
If your sub.unsubscribe(roomChannelName); call failed to issue an unsubscribe/punsubscribe, then that is a library issue, not a redis issue.
you can try somthing like that ,
use psubscribe and handle only if the pmesseege enter data
fits your needs..
const RedisInstance = require("./redis");
const Subscriber = new RedisInstance().client;
const socketsDataList = require('./activeSocketsList');
const orderManager = require("./orderManager");
class RedisSubscriber {
subscriber = Subscriber;
constructor() {
this.subscriber.psubscribe(`order_*`);
this.subscriber.on("pmessage", (pattern , channel , order) => this.onOrder(
channel , order) );
}
async getSocketByDeviceId(deviceId) {
return await socketsDataList.checkIfSocketExistsForThisDevice(deviceId);
}
async onOrder(channel , order ) {
const deviceId = channel.split("_")[1];
try {
const socketObj = await this.getSocketByDeviceId(deviceId);
if (socketObj['error']) {
console.log(socketObj['error']);
} else {
const socket = socketObj['activeSocket'].socket
await orderManager.sendOrderToClient( socket , order);
console.log({message: 'success'})
}
} catch (error) {
console.log(error)
}
}
}
module.exports = RedisSubscriber;
Related
I want to collect all transactions for an NFT.
For example, you can display all transactions here:
https://explorer.solana.com/address/2Nzt8TYeAfgJDftKzkb7rgYShVvyXTR7cPVvpqaZ2a4V
or here:
https://solscan.io/token/2Nzt8TYeAfgJDftKzkb7rgYShVvyXTR7cPVvpqaZ2a4V#txs
But is there any way to do this with the API?
I checked
solana-py: https://michaelhly.github.io/solana-py/
and solscan api: https://public-api.solscan.io/docs/
But I could not find a way to do it.
You can use the getSignaturesForAddress RPC method on the mint address and walk backward to get all the transactions.
Here is an example in JS:
import {
Connection,
clusterApiUrl,
ConfirmedSignatureInfo,
PublicKey,
} from "#solana/web3.js";
const connection = new Connection(clusterApiUrl("mainnet-beta"));
export const getTxs = async (connection: Connection, pubkey: PublicKey) => {
const txs: ConfirmedSignatureInfo[] = [];
// Walk backward
let lastTransactions = await connection.getConfirmedSignaturesForAddress2(
pubkey
);
let before = lastTransactions[lastTransactions.length - 1].signature;
txs.push(...lastTransactions);
while (true) {
const newTransactions = await connection.getConfirmedSignaturesForAddress2(
pubkey,
{
before,
}
);
if (newTransactions.length === 0) break;
txs.push(...newTransactions);
before = newTransactions[newTransactions.length - 1].signature;
}
return txs;
};
getTxs(
connection,
new PublicKey("2Nzt8TYeAfgJDftKzkb7rgYShVvyXTR7cPVvpqaZ2a4V")
);
The equivalent method in Solana.py is this one https://michaelhly.github.io/solana-py/rpc/api/#solana.rpc.api.Client.get_signatures_for_address
let file = fileUpload.files[0];
let offset = 0;
let chunkSize = 1024*1024*16;
file.arrayBuffer().then((buffer) => {
while(buffer.byteLength){
const chunk = buffer.slice(0, chunkSize);
buffer = buffer.slice(chunkSize, buffer.byteLength);
dataChannel.send(chunk);
}
})
it works fine for small files but stops with big size files.
A DataChannel has a bufferedAmount property which tells you how many bytes are still waiting to be sent. It also has a property called bufferedAmountLowThreshold.
The RTCDataChannel property bufferedAmountLowThreshold is used to specify the number of bytes of buffered outgoing data that is considered "low."
https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/bufferedAmountLowThreshold
https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/bufferedAmount
You could keep sending data as normal as long as bufferedAmount is below bufferedAmountLowThreshold. Once it is larger you stop queuing more data until you receive a bufferedamountlow event.
const send = () => {
while (buffer.byteLength) {
if (dataChannel.bufferedAmount > dataChannel.bufferedAmountLowThreshold) {
dataChannel.onbufferedamountlow = () => {
dataChannel.onbufferedamountlow = null;
send();
};
return;
}
const chunk = buffer.slice(0, chunkSize);
buffer = buffer.slice(chunkSize, buffer.byteLength);
dataChannel.send(chunk);
}
};
send();
I've searched similar topics here, but I still haven't resolved my problem. Maybe somebody can help me with this.
My goal is to display the logs from various services. To do that I am using signalR with vuejs as a client. I want to connect to the group of services on button click and fetch logs. When I click on a different button I want to leave the group and join another.
selectItem(name) {
this.groups.push(name)
document.getElementById('messageList').innerHTML = ''
const connection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:5000/logs")
.configureLogging(signalR.LogLevel.Information)
.build()
if (this.groups.length > 1) {
let previousGroup = this.groups[this.groups.length - 2]
connection.invoke("LeaveGroup", previousGroup)
console.log('leaving group:', previousGroup)
}
connection.on("PushEventLog", (message) => {
const div = document.createElement('div')
div.textContent = message
document.getElementById('messageList').appendChild(div)
})
connection.start().then(() => {
connection.invoke("JoinGroup", name)
console.log('joining group: ', name)
})
}
On my first joining to group everything works fine, but when I leaving the group and want to join another I receive an error:
Any help?
You are creating a new connection every time selectItem runs. You should store the connection object somewhere and only use it after it has started.
Added a couple comments to your code to point out what you're doing wrong.
// new connection object
const connection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:5000/logs")
.configureLogging(signalR.LogLevel.Information)
.build()
if (this.groups.length > 1) {
let previousGroup = this.groups[this.groups.length - 2]
// using new connection that hasn't started yet
connection.invoke("LeaveGroup", previousGroup)
console.log('leaving group:', previousGroup)
}
I've found a solution - I have moved connection and logs to the created hook. Working code below.
methods: {
selectItem(name, i) {
this.groups.push(name)
document.getElementById('messageList').innerHTML = ''
if (this.groups.length > 1) {
let previousGroup = this.groups[this.groups.length - 2]
this.connection.invoke("LeaveGroup", previousGroup)
} else {
this.connection.invoke("JoinGroup", name)
}
}
}
created() {
this.connection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:5000/logs")
.build()
this.connection.start()
this.connection.on("PushEventLog", (message) => {
const div = document.createElement('div')
div.textContent = message
document.getElementById('messageList').appendChild(div)
})
}
I am not sure if the issue I am having is a limitation in redis itself or in the nodejs 'redis' module implementation.
var redis = require('redis');
var client = redis.createClient(6379,'192.168.200.5');
client.on('error',function (error) {
console.log("** error in connection **");
process.exit(1);
});
client.on('connect',function () {
console.log("** connected **");
client.on('message',function (channel,message) {
if (channel == 'taskqueue') {
console.log(channel + ' --> ' + message);
var params = message.split(' ');
var inputf = params[0];
var outputf = params[1];
var dim = inputf.split('_').slice(-1)[0];
client.rpush('records',message,function (e,reply) {
});
}
});
client.subscribe('taskqueue');
});
From the code snippet above, I tried to do an RPUSH inside an "ON MESSAGE" subscription event. It does not work, and I get a client 'ON ERROR' event, thus, it prints error in connection. What is the correct way to do this?
After further searching, I came across this page https://github.com/phpredis/phpredis/issues/365 which seems to explain the scenario.
I have been trying to establish peer connection between browsers, to use data channel, but i am unsuccessful.
Everytime I correct one statement another error appears.
First I established a socketting server using socket.io and Node.js. In the server when any client is connection I am sending 'beacon' packets. On listening 'beacon' packet 1st client requests to join a 'room'. Then I allow the second client to join the same 'room'.
As soon as the second client connects, Server sends a confirmation packet to Client 1.
Then Client 1 sends the RTC Peer Connection 'offer' to Client 2, after setting local Description.
if( isChrome ) {
localPC = new window.webkitRTCPeerConnection(server, contraints);
rslt.innerHTML = "Webkit Variables Set";
}else {
localPC = new mozRTCPeerConnection(server, contraints);
rslt.innerHTML = "Mozilla Variables Set";
}
localPC.onicecandidate = function(event) {
if( event.candidate )
localPC.addIceCandidate( event.candidate );
};
localPC.onnegotiationneeded = function() {
localPC.createOffer( setOffer, sendFail );
};
sendChannel = localPC.createDataChannel( "sendDataChannel", {reliable: false} );
localPC.ondatachannel = function(event) {
receiveChannel = event.channel;
receiveChannel.onmessage = function(event) {
rslt.innerHTML = event.data;
};
};
localPC.createOffer( setOffer, sendFail );
function setOffer( offer ) {
lDescp = new RTCSessionDescription(offer);
localPC.setLocalDescription( lDescp );
socket.emit( 'offer', JSON.stringify(offer) );
rslt.innerHTML += "Offer Sent...<br/>";//+offer.sdp;
}//End Of setOffer()
Client 2 on receiving the 'offer' sets its as remote Description and creates a 'reply'. Sets the 'reply' as local Description, and sends it.
if( message.type == 'offer' ) {
rDescp = new RTCSessionDescription(message.sdp);
localPC.setRemoteDescription( rDescp );
localPC.createAnswer(
function( answer ) {
lDescp = new RTCSessionDescription(answer);
localPC.setLocalDescription( lDescp );
socket.emit( 'reply', JSON.stringify(answer) );
}, sendFail
);
}else {
localPC.addIceCandidate = new RTCIceCandidate( message.candidate );
}//End Of IF ELse
Client 1 on receiving the 'reply' sets it as remote Description and the connection should get established???
localPC.setRemoteDescription( new RTCSessionDescription( message.sdp ) );
But its not working!!! Pleease Help.
Seems like you got the flow correct, although I don't see the entire code.
One thing that strikes me weird is this:
localPC.onicecandidate = function(event) {
if( event.candidate )
localPC.addIceCandidate( event.candidate );
};
You need to send the icecandidate recieved in the onicecandidate event to the other peer. and not add it yourself.