Git Product home page Git Product logo

mqtt-react-hooks's People

Contributors

alexgorbatchev avatar andyfang94 avatar aposhian avatar dependabot[bot] avatar gstvg avatar semantic-release-bot avatar victorhas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

mqtt-react-hooks's Issues

messages are not deleted from store with mqtt 4.3.5 as dependency

mqtt-react-hooks declares the dependency for mqtt as "^4.2.8", which at the time of writing will install mqtt 4.3.5 on a fresh installation. This results in published messages not being deleted from the outgoing mqtt.Store with qos 1, even if PUBACK is received. Forcing the dependency to mqtt 4.2.8 resolves the problem.

Unable to use variables or objects for connection

I'm trying to do the following in React with the mqtt-react-hooks:

  • Get a url from a JSON config file
  • Get user info (username/password) from the server as each user has a different one

This is an example of the function that I'm using (note the comments for additional info)

export default function MqttConn(){
    const url_works = "ws://mymqttserver:myport/mqtt"; // This works 
    const url_doesntwork = variable_from_json_config_file; // This doesnt work 
    
    // I need to call a function to get each users login info, so "myOptions" is initially blank 
    const [myOptions, setState]=useState({
        username:"",
        password:"",
        clientId:"",
        keepAlive: 60, 
        clean: true
      });

    useEffect(()=>{
        My_Function_Checks_Server('someFunction', (error,response)=>{
            if(e){console.log(e)}
            //--- 
            setState({
                username: response.mqttUser,
                password: response.mqttPass,
                clientId: response.mqttTopic
            });
            //---  
        });        
    }, []); 
    
    return (
        <Connector brokerUrl={url_works} options={myOptions}>
            <Status/>
            <div>
                Test area for "setState" {/* This proves that all variables are fetched and correct*/} 
                <ul>
                    <li> Username: {myOptions.username} </li>
                    <li> Password: {myOptions.password} </li>
                    <li> ClientId: {myOptions.clientId} </li>
                </ul> 
            </div> 
        </Connector>
    )
}

My observations are:

  • The hook can only accept a directly written string, importing json config does not work no matter what I do. The URL must be manually written
  • the Options parameters are successfully fetched from the server, but the hook doesn't accept those values. I can print them and verify that they work with the broker through a separate client. I have also use manually typed parameters and it works.

Without these features this plugin cannot scale, so can you please guide me on how to use the variables for this hook, whether through a json config or a server side function call?

Thank you

connectionsStatus not change after broker go off and on again

Originally posted by @coderantongmail in #13 (comment)

1- If I have several components that are independent of each other, I add a subscription to a topic in the right component with the appropriate logic, but the component that was subscribed to another topic automatically receives all messages from all subscriptions. Is this normal behavior or was it intended a little differently?

For example as in the screenshots below:

image

image

As a result, I had to do an additional check for the topic I needed, otherwise I received a bunch of unnecessary messages that should have been only in the diagnostic component.

2- After the second component has been destroyed, the subscription is saved all the same. It is necessary to make it possible to unsubscribe from the topic when the component is destroyed. More precisely, add the ability to unsubscribe in the library

3 - If I disable broker status not changed to reconnecting, this is bug. And if broker run again, mqtt is reconnect, but status in connectionStatus not change if broker is down.

image

Attempted import error: 'useSubscription' is not exported from 'mqtt-react-hooks'.

Hello VictorHAS! First of all, thank you very much for this repo, so incredibly useful.

tl;dr I'm getting this error when I call useSubscription().

./src/components/App.js
Attempted import error: 'useSubscription' is not exported from 'mqtt-react-hooks'.

I just got this app spun up and started messing with your library so everything in question is happening within App.js, which I've included below in its entirety.

As you can see I got useSubscribeState() to work, but it returns an entire array of all the MQTT messages. So impressive but too much! All I want is the latest message in [messages]. I suspect that useSubscription() will meet my needs but I'm running into that import error, which I thought may be useful to bring up here. Any and all advice/feedback is extremely welcomed - as you can tell I'm pretty new to React. Thank you very much!

import React from 'react';
import './App.css';

import { useMqttState, useSubscribeState } from 'mqtt-react-hooks';
import { useSubscription } from 'mqtt-react-hooks';

const App = () => {
  const { mqtt } = useMqttState();
  const { messages } = useSubscribeState();

  const sendMessage = (message) => {
    console.log('Sent over MQTT: ' + message);
    return mqtt.publish('@', message);
  }

  // const test = useSubscription('leapCurrentSpeed');
  // console.log(test);

  const updateSpeed = (messages) => {
    if (messages !== undefined && messages.length !== 0) {
      console.log(messages);
      // Sketchy way of getting to the last message in [messages]
      const messagesLength = messages.length;
      const message = JSON.parse(messages[messagesLength - 1].message);
      if (message.hasOwnProperty('currentSpeed')) {
        const { currentSpeed } = message;
        return currentSpeed;
      }
    }
    else {
      const currentSpeed = 100;
      // console.log('in else statement');
      return currentSpeed;
    }
  }

  return (
    <div className="App">
      <button onClick={() => sendMessage('test message')}>
        Send MQTT message
      </button>
      <div className="speedReading">
        {updateSpeed(messages)}
      </div>
    </div>
  )
}

export default App;

Posibility to use react16+ as peer dependency?

I'm working on a project that uses react 17, which means I'm having to be pinned to the most recent commit before the dependency update. Would it be possible to support older react versions?

New version?

So I have time to work with that lib again, but I need to know what I can improve. It seems that there is an incompatible version between react and mqttjs. I will be analyzing in the next few days and trying to correct these errors. Maybe, there is a version 3.0.0 with the code all refactored

Unable to connect to test brokers using certain URLs

I'm unable to connect to the Mosquitto test broker via the URL listed in the README (mqtt://test.mosquitto.org:1884). I have also tried:

  • mqtt://test.mosquitto.org:8883 - Fail
  • mqtt://test.mosquitto.org:1883/ - Fail
  • ws://test.mosquitto.org:8080/ - Fail
  • wss://test.mosquitto.org:8081/ - Connects

So far only the last URL connects. I suspect those using the MQTT protocol fail because MQTT.js can't open the TCP socket by default.

EDIT: The error I see is WebSocket connection to 'ws://test.mosquitto.org:1884/' failed

Doesn't support receiving binary mqtt messages

I'm working with a device that uses binary messages and publishing isn't a problem using Uint8Array, but after subscribing to a topic I never got any msgs. I'm seeing the messages in websocket communication in the browser's developer tools, so I suspect it is a result of the toString().

I just wanted to make an issue to note the limitation in case it is something others run into. I appreciate the effort put into the library and respect that this may not get fixed.

Having problems with VITEJS

Hey guys, just tried out mqtt-react-hooks with VITEJS and seems not compatible since it call node functions and would need polyfiller for VITEJS, but adding a node polyfiller does not helps, can something be done to make this library work with Vitejs?
Thanks!

Optional connection

I would like to control the connection using a state value. Can you please add a Boolean property "connect" to the Connector which will indicate if to perform a connection or not.
This will support:
`
const [connect, setConnet) = useState(false);

return (
<Connector connect={connect}
{children components here that will optionally require mqtt}
</Connector
)
`

useSubscription hook does not catch all messages

I'm using mqtt-react-hooks with Webpack 5 and React 18 (manually added polyfill dependencies to work) to connect via MQTT over WebSocket to the Aedes broker. On the other side, there's an IoT device that every time publishes 5 test messages on a received command.

I have a problem that the built-in useSubscription hook, which returns the received, doesn't catch all published messages that it should. For comparison, Paho MQTT and the MQTTX app catch all 5 messages, while this library catches only 3 or 4, very rarely all 5. All messages are binary because we're using Google Protocol buffers, but I guess that shouldn't be a problem. Because of that, I'm using the parser method parserMethod={msg => msg} on the Connector.

The source code to listen to the messages is as follows:

const { message } = useSubscription(deviceToCloudTopic);

useEffect(() => {
  if (message) {
	  onMessageArrivedHandler(message);
	  console.log(message);
  }
}, [message]);

Is this a known issue or am I doing something wrong?

MQTT attempts to reconnect every few ms

Hello! I am using

    "mqtt-react-hooks": "^2.0.3",
    "next": "11.1.2",
    "react": "17.0.2",
    "react-dom": "17.0.2"

In my setup, the Connector connects to ws://test.mosquitto.org:8080. I tried various other servers to verify this problem persists.

Even without a useSubscription hook, the module attempts to connect every few milliseconds.

image

Even though I get 101 switching protocols.

Interestingly, I also only get Status: undefined

This is the code:

import { Connector, useMqttState } from 'mqtt-react-hooks'

const Home: NextPage = () => {
	const { connectionStatus } = useMqttState()
	return (
		<div>
			<Connector brokerUrl="ws://test.mosquitto.org:8080">
				{ `Status: ${connectionStatus}` }
			</Connector>
		</div>
	)
}

export default Home

I added a codesandbox where I can also observe the problem: https://codesandbox.io/s/headless-water-8hfcv

Authentication?

Hi, im using a MQTT broker with authentication but cant figure out where to parse the credentials in this library.
Am I blind or is it not implemented yet? :)

thanks in advance

useSubscription returns undefined

In my code I do the following:

import { useSubscription } from 'mqtt-react-hooks';

const Freezer = (props) => {

    const { message } = useSubscription("camper/sensors/freezer")
    
    useEffect(() => {
        console.log(message)
    }, [message])

    return (
        <>
            <div>
                <AcUnit style={{ fill: "darkblue" }} />
                <span>Freezer {message?.topic} &deg;C</span>
            </div>
        </>
    );
}

export default Freezer;

However, the message variable remains undefined.

In MQTT Explorer I see that the topic exists and that is contains messages.
Also In the developer tools network tab I see messages being received.

Does someone have an idea what could be the problem?

How to Change MQTT broker

Is it possible to change MQTT Broker on the fly, ?

I have setup Local MQTT which is accessible via Local network,
So when ever phone is connected to wifi I want to use Local MQTT, and when phone connected to mobile internet it should connect to another MQTT over internet.

Uncaught ReferenceError: Buffer is not defined

Right now, every newly created example will fail to run in the browser, with the above error. This seems to be related to an import referenced in this issue, but I just can't seem to locate it in the code of "
mqtt-react-hooks". Also mentioned in this issue, so many MQTT libs have this problem right now.

To reproduce the issue:

Can reproduce every time. Some suggest to solve this by downgrading "react-script", but that's not a real fix and causes other problems.

package.json contents:

{
  "name": "mqtt-demo-react",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "mqtt-react-hooks": "^3.0.0-alpha.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "url": "^0.11.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

cant get message of 2 topic at a time

hi
i need to subscribe 2 topics in at a time.
so i pass 2 topic in 'useSubscription' with array but i just get message for first topic

for example like this:
image
const { message } = useSubscription(['topic/1', 'topic/2']);

is this correct?
Is it possible to receive message of 2 topics at the same time?

Originally posted by @mehrdad24 in #13 (comment)

is Having a array of all topic for state is good ?

I was thinking that we can have an object or map for the state where we can take a topic as key in obj. This would be more configuration for the developer. We are having many topics that are only giving updates about something and old information is not needed. You can think of live views which is getting an update when a new user is joining and leaving but we just need to have current live views information for this.

Seeking for help with lost of connection: Connection Closed: 1005

I have a react application with multiple components which are shown in a tab like structure like a browser with multiple tabs. Using mui buttons I'm able to display the corresponding tab however the MQTT connection closed with the 1005 errorcode. After trying lots of things I run out ideas so solve this.

Does someone have an idea what could be the problem?

  • When I place a alert in the onclick() in stead of the switch tab function the connection remained open and I can send messages using a switch button on the already displayed tab

Messages are never cleared

The message array (msgs) in useSubscription(topic) always returns all messages detected and are never cleared. This is effectively a memory leak since all messages are stored in that said array, imagine a IOT device pushing millions of messages to a topic and this array contains them all.

I feel that the message array should only contain the retained messages of the topic, also i feel like useSubscription should return a subscription function we could use to subscribe to new messages. Example:

const { subscribe, unsubscribe } = useSubscription("test");

useEffect(() => {
    const id = subscribe(message => {
        console.log(message);
    });

    return function cleanup() {
        unsubscribe(id);
    }
}, []);

OR

const { subscribe } = useSubscription("test");

useEffect(() => {
    const unsubscribe = subscribe(message => {
        console.log(message);
    });

    return function cleanup() {
        unsubscribe();
    }
}, []);

UseSubscription throws error: "i.off is not a function"

Hello, thanks again for writing this module. I am using nextJS which may be causing part of the behavior issues, or be unrelated. I open a connector in the app.js and I can connect fine and see connection status in another page using:

const { connectionStatus } = useMqttState();

however this throws the error:
const { message } = useSubscription('queuesList');


code in skillpage:

import React, { useEffect, useState } from 'react';
import { useMqttState, useSubscription } from 'mqtt-react-hooks';

export default function SkillPage() {
const { connectionStatus } = useMqttState();
const { message } = useSubscription('queuesList');

return (

{connectionStatus}
)} ------------------------------------------------------------

The i.off line of code is in your index.es.js file. Also I noticed if I import client, then do client.subscribe - that works fine still.

How can we use authentication?

How can we use authentication with MQTT username and password?

Use the provided example I tried this

export default function MqttConn(){
    const url = "some url:port"   
    return (
        <Connector brokerUrl={url}>
            <Status/>
        </Connector>
    )
}

The status shows as "Connecting" which is expected, but I need to provide username and password to connect. Please help.

Thanks

Client disconnecting and reconnecting using local mosquitto broker

Hello,

I'm using docker container running a mosquitto broker. Works fine with mqtt.js library. However, when I try to use the Connector provider it disconnects/reconnects on a loop. Here's the output:

mosquitto  | 1668119874: New client connected from ::ffff:172.23.0.1:57598 as mqttjs_41060487 (p2, c1, k0).
mosquitto  | 1668119874: No will message specified.
mosquitto  | 1668119874: Sending CONNACK to mqttjs_41060487 (0, 2)
mosquitto  | 1668119874: Client mqttjs_41060487 closed its connection.

I'm using vite and added the following line to the vite config resolve: { alias: { mqtt: "mqtt/dist/mqtt.js" }
I got it to work with test.mosquitto.org but then ran into the client undefined issue

#41

I'd love to get this working locally. Here' is my mosquitto.conf

persistence false
listener 1883
allow_anonymous true
listener 8083
protocol websockets

Here is a similar issue with a Node Red client:

eclipse/mosquitto#2381

Thanks!

TypeError: Cannot read properties of undefined (reading 'topic')

I got a error from use Subscription example ( TypeError: Cannot read properties of undefined (reading 'topic') )

`import React from 'react';

import { useSubscription } from 'mqtt-react-hooks';

export default function Status() {
/* Message structure:

  • topic: string
  • message: string
    */
    const { message } = useSubscription([
    'room/esp32/testing',
    'room/esp32/light',
    ]);

return (
<>
<div style={{ display: 'flex', flexDirection: 'column' }}>
{topic:${message.topic} - message: ${message.message}}

</>
);
}`
How can I fix it

useSubscription resubscribes on each message received

If I make a very simple component that displays data from a subscription, I have found that it resubscribes every time it receives a new message. This is inefficient, and causes extra latency. My guess is that because the Mqtt client is passed through the context, message receipt changes the client, which then causes the consumers of the mqtt context to rerender. I am looking into this right now.

Stuck in connection state, multiple websocket connections openned.

Hello everyone,
I am stuck using this package, which by the way seems to be nice and easy to use.
I am not able to connect to my broker using it.

imageThe client state is null
The connectionStatus is stuck in "Connecting"
Moreover, in the network tab, 3 WS connections are initiated (101 Switching protocols) to my broker.
Why are 3 connection openned ? I logged how many renders occurs, and there is only one render.

I tried to reproduce this package using plain JS with the same code, and i can tell that the problem seemed to by related to the mountedRef ref, which happen to never be equal to true when entering in all listeners (on.connect , on.reconnect, on.error , etc. ) and so, never setting up the client or updating the connectionStatus.
Maybe my issue is related to the ref.

By the way, the broker is fully working, as I was previously using plain mqtt package without no issues. Tested also with public mqtt brokers, same results.

If someone has an idea ?
Thanks a lot !

connectionStatus does not change when the mqtt server closes the connection

I've got a mosquitto broker set up on my machine that exposes a websocket on port 9001. Here's my configuration file contents:

mosquitto.conf

allow_zero_length_clientid true
max_keepalive 65535
listener 1883
protocol mqtt
listener 1884 localhost
protocol mqtt
listener 9001
protocol websockets
require_certificate false
log_type all
websockets_log_level 1
allow_anonymous true

I have a very simple application that I believe others have used before to point out issues with connectionStatus.

App.tsx:

import { IClientOptions } from 'mqtt';
import { Connector } from 'mqtt-react-hooks';
import Status from './Status';

const options: IClientOptions = {keepalive: 10, clientId: 'MyClient'};
const brokerUrl = "ws://localhost:9001";

function App() {

  return (
    <Connector brokerUrl={brokerUrl} options={options}>
        <Status />
    </Connector>
  );
}

export default App;

Status.tsx:

import { useMqttState } from 'mqtt-react-hooks';

const Status = () => {
    const {connectionStatus} = useMqttState();

    return (
        <div>{connectionStatus}</div>
    );
}

export default Status;

If start with the mosquitto broker turned off, then turn it on, the page will correctly show the Reconnecting, Offline, and Connected connectionStatuses (in that order). I also get a websocket console error while the mosquitto broker is offline.

However, once I CTRL+C to kill the mosquitto broker, the connectionStatus continues to be shown as Connected, even though it is very obviously Offline.

In order to address this, I completely removed the mountedRef from Connector.tsx. I didn't understand what the point of this was. Likely because I'm so new to React. Once I removed all lines referencing mountedRef, I also added two more mqtt.on lines inside the useCallback to handle disconnect and close.

Suport for webpack 5.66.0

My error is:

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "url": require.resolve("url/") }'
- install 'url'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "url": false }

package.json :

{
"name": "mqtt-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"mqtt-react-hooks": "^2.0.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

How to connect Over TCP

Hi Team,

Am trying to connect over TCP Protocal. By default it's connecting By ws://

Where do i change that ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.