FreeOpcUa / python-opcua

LGPL Pure Python OPC-UA Client and Server
http://freeopcua.github.io/
GNU Lesser General Public License v3.0
1.36k stars 658 forks source link

Server with several endpoints #712

Open MikelAyani opened 6 years ago

MikelAyani commented 6 years ago

Hi, I was wondering why the internal server can handle several endpoints, but the Server class just can have one. According to my tests, changing the endpoint URL in the Server class, it overrides the old one. I am asking this because I think it would be interesting to be able to reach the server, for example, from the same machine using opc.tcp:\localhost:4840 and remotely with opc.tcp:\192.168.1.12:4840 (assuming the machine has this IP). That way, the clients running locally do not need to know the local IP address. I wonder if this could also be useful if the server machine has several IP addresses and having endpoints for each address it could be visible from different networks. I hope it makes sense... I haven't found any example of adding extra endpoints so that's why I am asking here. Thanks in advance! //Mikel

zerox1212 commented 6 years ago

That is a strange request. I would think that having a server accessible from multiple addresses would be more confusing in the case you describe. This seems like a nonstandard requirement you would need to implement yourself.

BTW, the Server class wraps a lot of things to make it easy for users to create a server in a few lines of code. There isn't any reason you can't write your own code and deal directly with things like internal server so that it does multiple endpoints like you want.

MikelAyani commented 6 years ago

Ok, thanks for your answer. PLCs for example can also have two different IP addresses for two different networks. For me, it sounds quite natural to make the opcua server available for both networks having 2 different endpoints. In my case, the server runs in a PC with 2 network cards and 2 IP addresses... Clients can try to reach the server locally and from both networks. The link below also mentions that different endpoints can be created for a server: http://www.opclabs.com/files/onlinedocs/QuickOpc/Latest/User%27s%20Guide%20and%20Reference-QuickOPC/Server%20Endpoints.html I think (just looking to the code) that the internal server already supports several endpoints now, anyway... But I do not see how to add extra endpoints from the Server class.

zerox1212 commented 6 years ago

I would have to look closer. @oroulet probably has a reason for the current design.

Could you try adding more endpoints directly at internal server and test if it actually works (for example a single server listening on two network cards)?

oroulet commented 6 years ago

Write 0.0.0.0 as the IP address and it will listen to all interfaced on PC. The address is directly passed to the asyncio socket. You should probably read doc of socket if you want two specific interfaces

oroulet commented 6 years ago

Btw some clients do not like 0.0.0.0 as endpoint. There is a PR for that but it is hard to make it robust...

brubbel commented 6 years ago

Yes, above mentioned test branch is here, and for the time being it is working without issues for me. PR will be updated should an issue arise.

The PR relies on the fact that clients embed the server endpoint IP in their own discovery request, so we can use that to append to the available endpoints. Requirement for the patch is that the server is started with '0.0.0.0' or '::' (IPv6) as listening iface.

So, please test and comment :-)

milgner commented 3 years ago

I'm still very new to the whole OPC UA topic but I read about one system where multiple OPC UA endpoints were used to expose different information: One without authentication to expose a bit of basic information and one which required authentication to expose the real information. Of course I realize that this could also be solved by checking the role of the connected user but it would still be useful to replicate such setups with the Python library.