I'm using Monaco's editor simply to display simple examples of HTML, XML, and other language formats. No codebases are used here—simple files only.
Currently, we are using a custom WebSocket server to broadcast changes made to a single file to everyone in the room.
For some reason, Monaco's editor is opening a second connection to another room in the WS service
I would like to completely overwrite this service so that Monaco's editor doesn't interfere with my Websocket connections.
From the docs I can pass a third argument to the constructor to overwrite editor services. What I have tried so far
const websocketService = {
getName() {},
doOpen() {},
addEventListeners() {},
write() {},
doClose() {},
uri() {},
check() {},
}
editorMonaco = monaco.editor.create(document.getElementById('file_editor'), {
value: data,
language: 'xml',
automaticLayout: true
}, {
wsService: websocketService,
websocketService,
websocket: websocketService,
webSocket: websocketService,
webSocketService: websocketService,
});
Unfortunately, it isn't working with either one of the keys.
How can I completely disable Websocket interference from Monaco's editor? The Websocket communication is being handle by us
Related
In a graphql query with multiple resolvers, I'm looking for a way to count how many times datasources are called before the first datasource API request is sent. The project that I am working on requires me to either allow or stop all the requests if the number of the datasources called within resolvers in a graphql query exceeds a certain number.
I am using an instance of the RESTDataSource to make API calls and each one of the resolvers call one or more datasources from the RESTDataSource class. I've been looking into this and far as I know, the RESTDataSource class doesn't have a method that shows me all the datasources requested because it is only called by the resolver and per request.
My problem is, I'm not finding a place where I can have access to all the datasources that will be called before the request is sent. I found that in the Apollo server instantiation, the only thing that I have access to are the resolvers, and not the datasources within each resolver, and as far as I know, not before the request is made so I can't stop it if the number of datasources calls exceed a certain threshold. I was hoping I could access that in the willSendRequest method inside the RESTDataSource class since from what I know, this is the only method that intercepts the request before being sent, but I don't think it's possible.
I'm pretty new to Apollo and I've been reading about this but didn't find a solution. I'd really appreciate any help.
Here's a simplified snippet of my code (not the original code):
resolvers.ts
export const resolvers: Resolvers = {
Query: {
getCompanies: (_, __, { dataSources }) => {
return dataSources.companyDatasource.getCompanies();
},
getCompany: (_, { name }, { dataSources }) => {
return dataSources.companyDatasource.getCompanyByName(name);
},
getCompanyCEOs: async (_, { name }, { dataSources }) => {
const company = await dataSources.companyDatasource.getCompanyByName(name);
return dataSources.companyDatasource.getCEOs(company.id);
},
....
company.datasource.ts
export default class CompanyDatasource extends RESTDataSource {
async willSendRequest(request) {
// some logic
}
async getCompanies() {
return this.get(`some_api_url`);
}
async getCompanyByName(name) {
return this.get(`some_api_url?companyName=name`);
}
//other external API endpoints
...
}
main.ts
const server = new ApolloServer({
typeDefs: schema,
schema,
resolvers,
dataSources,
cache: 'bounded',
});
await server.start();
Edit: I'm limiting the number of unique datasource API calls because the API I'm hitting has a limit. I tried instantiating a counter in the RESTDataSource class and using it in the willSendRequest to count how many datasource calls there are, but the problem is this is counting request by request and has no access to all the API requests that are coming from the resolver. For instance, if the getCompanies API can be called only once and I have 2 upcoming requests, I'll have to let one of them pass and only stop the second, because at that point I don't know there's a second request coming. My team has agreed to stop both requests in case the number of upcoming requests exceeds the available limit for the endpoint (this is specified in our database), so this is why I need to know beforehand how many API requests are there before even allowing the first request.
I'm trying to make socket.io-client work in a svelte front end app to talk to an existing API server that already uses socket.io. After a number of challenges, I managed to make this work but I can only get this to work with sveltekit's preview and not in dev mode. Wondered if someone with some knowledge of those could explain why or suggest what I need to do to get it connecting in dev?
svelte 3.34.0
sveltekit next-169
socket.io(-client) 4.2.0
basic code as follows, currently within a file $lib/db.js where I define a few stores that are pulled into the layout for general use..
import { io } from "socket.io-client";
import { browser } from '$app/env';
const initSocket = async () => {
console.log('creating socket...');
let socket = io('http://192.168.1.5:4000', { 'connect timeout': 5000 });
socket.on("connect", () => {
// always works in preview...
console.log('socket created with ID:', socket.id);
});
socket.on("connect_error", (error) => {
// permanently fired in dev...
console.error('Failed to connect', error);
});
socket.on("error", (error) => {
console.error('Error on socket', error);
});
socket.on("foo", data => {
// works in preview when server emits a message of type 'foo'..
console.log("FOO:", data);
});
};
if (browser) {
initSocket();
}
// stores setup and exports omitted..
with svelte-kit preview --host I see the socket creation log message with the socket ID and the same can be seen on the api server where it logs the same ID. The socket works and data is received as expected.
with svelte-kit dev --host however, the log message from socket.on("connect").. is never output and I just see an endless stream of error messages in the browser console from the socket.on("connect_error").. call..
Failed to connect Error: xhr poll error
at XHR.onError (transport.js:31)
at Request.<anonymous> (polling-xhr.js:93)
at Request.Emitter.emit (index.js:145)
at Request.onError (polling-xhr.js:242)
at polling-xhr.js:205
Importantly, there is no attempt to actually contact the server at all. The server never receives a connection request and wireshark/tcpdump confirm that no packet is ever transmitted to 192.168.1.5:4000
Obviously having to rebuild and re-run preview mode on each code change makes development pretty painful, does anyone have insight as to what the issue is here or suggestions on how to proceed?
I've had a similar problem, I solved it by adding this code to svelte.config.js:
const config = {
kit: {
vite: {
resolve: {
alias: {
"xmlhttprequest-ssl": "./node_modules/engine.io-client/lib/xmlhttprequest.js",
},
},
},
},
};
The solution was provided by this comment from the vite issues.
I have a page that is loading connected apollo-client pages as widgets inside of a main page. My GraphQL server is self-hosted. They are served up through iFrame (self-hosted), connecting back to my own server. Communications are done through a 3rd party's iFrame communications SDK.
For some reason the widgets are not cleared out from the window when they are stale (I have no control over this). However I do have access to know when they are "stale". When they turn stale I want to disconnect / shutdown the websocket connection. The trouble is the still-connected clients are eating up my back-end's CPU. I am watching the websocket connection through chrome dev-tools. I notice every 5 seconds it sends a keep-alive request to the websocket sever. Every so often I see a stop request, and I want to figure out how to replicate that.
Im my react apollo-connected component I tried calling these two commands, but after they are called with no errors, the keep-alive flags are still being sent to the websocket server.
this.props.client.stop()
this.props.client.clearStore();
How do I tell the apollo-client to shut itself down?
For Apollo V3, the WebSocketLink has an internal SubscriptionClient instance, but the problem is that WebSocketLink doesn't expose methods that give you access to the SubscriptionClient instance, so there's no accessing SubscriptionClient.close(). Fortunately, WebSocketLink accepts a client as an argument:
const subscriptionClient = new SubscriptionClient(`wss://example.com/subscriptions`, {
// example options:
reconnect: true,
lazy: true,
connectionParams: () => ({ accessToken: 'secret' }),
});
const wsLink = new WebSocketLink(subscriptionClient);
Now you just need to move subscriptionClient into a context in order to gain access to the client in various places:
export const SubscriptionClientContext = createContext<
SubscriptionClient | undefined
>(undefined);
export const useSubscriptionClient = (): SubscriptionClient => {
const subscriptionClient = useContext(SubscriptionClientContext);
if (subscriptionClient === undefined) {
throw Error(
'SubscriptionClient not initiated, can only be called inside SubscriptionClientContext.Provider',
);
}
return subscriptionClient;
};
<SubscriptionClientContext.Provider value={subscriptionClient}>
<App />
</SubscriptionClientContext.Provider>
This will let you access methods on the client for logout behavior in various parts of the app:
const subscriptionClient = useSubscriptionClient();
subscriptionClient.close();
There are also two arguments for .close, that have various behaviors. E.g. close and reconnect, close and do not reconnect.
Here's a small issue I faced and couldn't find much info in the documentation. I am trying to create private chat messages. We have the following code to subscribe a user to a topic:
export const resolvers = {
Subscription: {
somethingChanged: {
subscribe: () => pubsub.asyncIterator('chat_messages'),
},
},
}
and to publish
pubsub.publish('chat_messages', { somethingChanged: { sender_id: 1, receiver_id: 2, message: 'test' }});
I have used onConnect to verify that the user is authenticated
const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
onConnect: (connectionParams, webSocket) => {
...
if (!authenticated) throw error
...
},
},
...
})
This works well when I want to subscribe users to a particular topic for example. But how do I implement, private user to user communication? I have tried the withFilter but can't seem to implement user specific authorization(with respect to a message) checks.
Here is a demo: https://github.com/mrdulin/apollo-server-express-starter/tree/master/src/subscription/demo-1
With these features:
jwt based auth for websocket connection
User channel which means who can receive message, who can not.
There are some conceptions you need know:
there are two types user: requestUser and subscribeUsers(include requestUser)
you should write the code in filterFn, for who can receive the message which requestUser send.
For example:
There are three subscribe users: s1(client-1), s2(client-2), s3(client-3)
When a request user(client-4) send a message(maybe mutation), you can get subscribe users and request users through context argument of filterFn.
According to these two type users' informations. You can write your own bussiness logic in filterFn to decide who can receive message, who can't.
P.S. beside context, you can get variables argument in filterFn from client. That will give more information to decide who can receive message and who can't
Sorry for my English!
Is it possible to connect any external application to my sails.js application via WebSockets?
I can use the underlying socket.io embedded in sails.js to talk between the client and server, that's not a problem.
But, I would like to connect another, separate, application to the sails.js server via websockets, and have those two communicate with each other that way, and I am wondering if this is possible?
If so, how can we do this?
Thanks.
Based on SailsJS documentation, we have access to the io object of socket.io, via sails.io.
From that, I just adjusted boostrap.js:
module.exports.bootstrap = function (cb) {
sails.io.on('connection', function (socket) {
socket.on('helloFromClient', function (data) {
console.log('helloFromClient', data);
socket.emit('helloFromServer', {server: 'says hello'});
});
});
cb();
};
Then, in my other nodejs application, which could also be another SailsJS application and I will test that later on, I simply connected and sent a message:
var io = require('socket.io-client');
var socket = io.connect('http://localhost:3000');
socket.emit('helloFromClient', {client: 'says hello'});
socket.on('helloFromServer', function (data) {
console.log('helloFromServer', data);
});
And here are the outputs.
In SailsJS I see:
helloFromClient { client: 'says hello' }
In my client nodejs app I see:
helloFromServer { server: 'says hello' }
So, it seems to be working just fine.