An RPC can be thought of as a wrapper placed around an M entry point for use with client applications. Each RPC invokes a single M entry point. The RPC passes data in specific ways to its corresponding M entry point, and expects any return values from the M entry point to be returned in a pre-determined format. This allows client applications to connect to the RPC Broker, invoke an RPC, and through the RPC invoke an M entry point on a server.
You can use the $$BROKER^XWBLIB function in M code to determine whether the code is being run in an environment where it was invoked by the Broker. This may help you use M code simultaneously for Broker and non-Broker applications.